| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- #ifndef CANCLIENT_H
- #define CANCLIENT_H
- #include <QThread>
- #include <QCanBusDevice>
- #include <QCanBus>
- #include <QMap>
- #include <QList>
- #include <QMutex>
- #include <QString>
- #include <QByteArray>
- #include <QTimer>
- #include <QtQml/qqml.h>
- #include "define.h"
- #define CAN_SLEEP_TIME 50
- // 响应回调函数类型定义
- using CANResponseCallback = std::function<void(const QCanBusFrame& respFrame)>;
- typedef struct {
- bool success = false; // 读取是否成功
- quint8 nodeId = 0;
- bool leftHasKey = false; // 左钥匙是否存在
- bool leftCharging = false; // 左钥匙是否充电中
- bool rightHasKey = false; // 右钥匙是否存在
- bool rightCharging = false; // 右钥匙是否充电中
- } CANKeyBaseStatus;
- Q_DECLARE_METATYPE(CANKeyBaseStatus)
- typedef struct {
- bool success = false; // 读取是否成功
- quint8 nodeId = 0;
- bool leftLocked = false; // 左钥匙是否锁住
- bool leftCharging = false; // 左钥匙是否充电中
- bool rightLocked = false; // 右钥匙是否锁住
- bool rightCharging = false; // 右钥匙是否充电中
- bool leftBuckleFault = false; // 左卡扣故障
- bool rightBuckleFault = false; // 右卡扣故障
- } CANKeyBaseControlStatus;
- Q_DECLARE_METATYPE(CANKeyBaseControlStatus)
- typedef struct {
- bool success = false; // 读取是否成功
- quint8 nodeId = 0;
- QList<int> lockNums;
- QMap<int, bool> lockHasKeyMap; // 1-5号锁有锁/无锁(索引0=1号锁)
- QMap<int, bool> lockFaultMap; // 锁故障状态(key=锁号)
- } CANLockControlStatus;
- Q_DECLARE_METATYPE(CANLockControlStatus)
- typedef struct {
- int lockNum = 0; // 锁号1-5
- quint8 nodeId = 0;
- bool isWorking = false; // 设置工作状态
- bool isLocked = false; // 设置锁定状态
- } CANSingleLockStatus;
- Q_DECLARE_METATYPE(CANSingleLockStatus)
- typedef struct {
- bool success = false;
- quint8 nodeId = 0;
- QList<int> lockNums;
- QMap<int, bool> lockWorkMap; // 设置工作状态(key=锁号)
- QMap<int, bool> lockLockedMap; // 设置锁定状态(key=锁号)
- } CANLocksControl;
- Q_DECLARE_METATYPE(CANLocksControl)
- typedef struct {
- bool success = false; // 读取是否成功
- quint8 nodeId = 0;
- QString leftKeyRFID; // 左钥匙卡号
- QString rightKeyRFID; // 右钥匙卡号
- bool leftKeyReadSuccess = false; // 左钥匙单独读取成功标记
- bool rightKeyReadSuccess = false; // 右钥匙单独读取成功标记
- } CANKeyRFIDStatus;
- Q_DECLARE_METATYPE(CANKeyRFIDStatus)
- typedef struct {
- bool success = false; // 读取是否成功
- quint8 nodeId = 0;
- QMap<int, QString> lockRFIDMap; // 各锁卡号(key=锁号)
- QMap<int, bool> lockReadSuccessMap; // 各锁读取成功标记(key=锁号)
- } CANLockRFIDStatus;
- Q_DECLARE_METATYPE(CANLockRFIDStatus)
- enum class ChargeState {
- Uncharged = 0, // 未充电
- Charging = 1, // 充电中
- };
- typedef struct {
- bool success = false; // 读取/写入是否成功
- quint8 nodeId = 0;
- // 可写控制项(仅充电使能)
- bool leftChargeEnable = false;// 左卡扣充电使能(1=开启,0=关闭)
- bool rightChargeEnable = false;// 右卡扣充电使能
- // 只读状态项(设备反馈)
- bool leftLocked = false; // 左卡扣上锁状态(1=上锁)
- bool rightLocked = false; // 右卡扣上锁状态
- bool leftWorking = false; // 左卡扣工作状态(1=工作中)
- bool rightWorking = false; // 右卡扣工作状态
- ChargeState leftChargeState = ChargeState::Uncharged; // 左卡扣充电细分状态
- ChargeState rightChargeState = ChargeState::Uncharged; // 右卡扣充电细分状态
- } CANKeyBaseChargeStatus;
- Q_DECLARE_METATYPE(CANKeyBaseChargeStatus)
- typedef struct {
- QMap<QString, quint8> keysMap;
- QMap<QString, quint8> locksMap;
- } CANReturnKeyDevices;
- Q_DECLARE_METATYPE(CANReturnKeyDevices)
- class CANClient : public QThread
- {
- Q_OBJECT
- QML_NAMED_ELEMENT(CANClient)
- Q_PROPERTY(bool workingKey READ workingKey WRITE setWorkingKey NOTIFY workingKeyChanged)
- Q_PROPERTY(bool workingLocks READ workingLocks WRITE setWorkingLocks NOTIFY workingLocksChanged)
- public:
- explicit CANClient(QObject *parent = nullptr);
- ~CANClient() override; // 补充析构函数,释放资源
- /* 连接或者断开 CAN 设备 */
- void connectDevice();
- /* 获取当前CAN设备连接状态 */
- bool isCanBusConnected() const { return m_canBusStatus; }
- // 异步发送CAN帧,通过回调返回响应
- void sendFrameAsync(const QCanBusFrame& frame, CANResponseCallback callback);
- void testFunc();
- QString getLockRFID(int lockNum);
- bool workingKey() const {
- return m_workingKey;
- }
- void setWorkingKey(bool isWorking) {
- m_workingKey = isWorking;
- emit workingKeyChanged();
- }
- bool workingLocks() const {
- return m_workingLocks;
- }
- void setWorkingLocks(bool isWorking) {
- m_workingLocks = isWorking;
- emit workingLocksChanged();
- }
- protected:
- void run() override;
- private:
- /* 初始化CAN总线插件列表 */
- void pluginItemInit();
- /* 初始化比特率和CAN设备实例 */
- void bitrateItemInit();
- public:
- /* 安全停止线程并释放资源 */
- void stopThreadAndRelease();
- QMap<quint8, CANKeyRFIDStatus> keyRFIDStatus() const {
- return m_keyRFIDStatus;
- }
- QMap<quint8, CANKeyBaseStatus> keyBaseStatus() const {
- return m_keyBaseStatus;
- }
- private slots:
- /* 接收CAN总线消息帧 */
- void receivedFrames();
- /* 处理CAN设备错误 */
- void canDeviceErrors(QCanBusDevice::CanBusError error) const;
- void slotUpdateKeyBaseStatus(quint8 nodeId, const CANKeyBaseStatus& status);
- // 根据读取到钥匙的状态(有/无钥匙和是否锁住)更新
- void slotUpdateKeyBaseControl(quint8 nodeId, const CANKeyBaseControlStatus& status);
- // 根据读取到5路锁的状态(有/无锁和是否锁住)更新
- void slotUpdateLockedStatus(quint8 nodeId, const CANLocksControl& status);
- void slotWorkingKeyChanged();
- void slotWorkingLocksChanged();
- signals:
- // 设备类型信息读取完成
- void deviceInfoRead(bool success, const quint8& nodeId);
- // 钥匙底座状态读取完成
- void keyBaseStatusRead(quint8 nodeId, const CANKeyBaseStatus& status);
- void keyBaseControlStatusRead(quint8 nodeId, const CANKeyBaseControlStatus& status);
- // 5路锁状态读取完成
- void lockStatusRead(quint8 nodeId, const CANLockControlStatus& lockHasKeyList);
- void lockControlStatusRead(quint8 nodeId, const CANLocksControl& status);
- void lockBuckleWritten(bool success, const QList<QString>& lockNfc);
- // 锁扣控制完成
- void lockBuckleWrite(bool success, int lockNum, bool isLock);
- // 温湿度读取完成
- void temperatureRead(bool success, double leftTemp, double rightTemp);
- void humidityRead(bool success, double humidity);
- // CAN设备连接状态变化
- void signalCanBusStatusChanged(bool isConnected);
- void keyRFIDStatusRead(quint8 nodeId, const CANKeyRFIDStatus& status); // 钥匙RFID读取完成
- void lockRFIDStatusRead(quint8 nodeId, const CANLockRFIDStatus& status); // 锁RFID读取完成
- void singleKeyRFIDRead(bool isLeftKey, bool success, const QString& rfidCard); // 单个钥匙RFID
- void singleLockRFIDRead(int lockNum, bool success, const QString& rfidCard); // 单个锁RFID
- void keyBaseChargeControlWritten(const CANKeyBaseChargeStatus& status);
- void singleKeyBaseChargeControlWritten(bool isLeftKey, bool success,
- bool chargeEnable, bool locked,
- bool working, ChargeState chargeState);
- void keyBaseChargeStatusRead(const CANKeyBaseChargeStatus& status);
- void workingKeyChanged();
- void workingLocksChanged();
-
- // ========== 归还钥匙和锁检测信号 ==========
- // 当检测到NFC设备插入时发出(用于归还流程)
- void nfcDeviceDetected(const QString& nfcId, const QString& deviceType, int slotIndex);
- void signalLockNfcDeviceDetected(const QString& nfcId);
- // 当检测到设备异常时发出(无法读取NFC)
- void nfcDeviceError(const QString& deviceType, int slotIndex);
- // ==========================================
-
- void signalReturnKey();
- void signalPopDevices(const QString& nfcId, const QString& deviceType, int slotIndex);
- private:
- // 处理设备主动上报的插入帧(归还流程)
- void handleDeviceInsertionFrame(const QCanBusFrame& frame);
-
- // 构造SDO读报文
- QCanBusFrame buildReadFrame(quint8 nodeId, quint16 index, quint8 subIndex);
- // 构造SDO写报文
- QCanBusFrame buildWriteFrame(quint8 nodeId, quint16 index, quint8 subIndex, const QByteArray& data, quint8 byteCount = 0);
- // 解析小端数据(16位)
- quint16 parseLittleEndian16(const QByteArray& data);
- // 解析小端数据(32位)
- quint32 parseLittleEndian32(const QByteArray& data);
- // 解析温度数据(有符号16位/10)
- double parseTemperature(const QByteArray& data);
- // 解析湿度数据(无符号16位/10)
- double parseHumidity(const QByteArray& data);
- // 解析RFID卡号(小端4字节)
- QString parseRFIDCard(const QByteArray& data);
- // bool verifyNodeID(quint8 deviceNodeId, quint8& returnNodeId);
- bool verifyAllNodeID(quint8 deviceNodeId, QList<quint8>& returnNodeId);
- ChargeState bitToChargeState(uint8_t bitValue) {
- switch (bitValue) {
- case 0: return ChargeState::Uncharged;
- case 1: return ChargeState::Charging;
- default: return ChargeState::Uncharged;
- }
- }
- QString chargeStateToString(ChargeState state) {
- switch (state) {
- case ChargeState::Uncharged: return "未充电";
- case ChargeState::Charging: return "充电中";
- default: return "未充电";
- }
- }
- private:
- // 检查锁扣编号有效性(1-5号)
- bool checkLockNumValid(int lockNum);
- // 检查RGB通道有效性(1-4路)
- bool checkRGBChannelValid(int channel);
- // 检查亮度值有效性(0-100)
- bool checkBrightnessValid(int bright);
- //
- void readDeviceInfoAsync(quint8 nodeId);
- // 电子钥匙底座
- void readAllKeyBaseStatusAsync();
- void readKeyBaseStatusAsync(quint8 nodeId);
- void readAllKeyBaseControlStatusAsync();
- void readKeyBaseControlStatusAsync(quint8 nodeId);
- // 5路挂锁底座
- void readAllLocksStatusAsync();
- void readLockStatusAsync(quint8 nodeId);
- void readAllLocksControlStatusAsync();
- void readLockControlStatusAsync(quint8 nodeId);
- void writeSingleLockBuckleAsync(const CANSingleLockStatus& status);
- void writeLockBuckleAsync(const CANLocksControl& status);
- // 温湿度
- void readTemperatureAsync(quint8 nodeId);
- // 批量读取:仅左+右钥匙
- void readAllKeyRFIDStatusAsync();
- void readKeyRFIDStatusAsync(quint8 nodeId);
- // 批量读取:仅1-5号锁
- void readAllLocksRFIDStatusAsync();
- void readLockRFIDStatusAsync(quint8 nodeId);
- // 单个读取:仅左/右钥匙
- void readSingleKeyRFIDAsync(quint8 nodeId, bool isLeftKey);
- // 单个读取:仅某一个锁
- void readSingleLockRFIDAsync(quint8 nodeId, int lockNum);
- // 左+右卡扣充电使能
- void writeKeyBaseChargeControlAsync(CANKeyBaseChargeStatus& chargeStatus);
- // 读取卡扣当前充电状态
- void readKeyBaseChargeStatusAsync(quint8 nodeId);
- public:
- bool openEKey(QString& keyNFC);
- bool unlockEKey();
- bool getLockRfids(int lockCount, QMap<int, QString>& rfids);
- bool unlockLocks(const QList<int>& lockNums);
- void unlockEKey(const QString& keyNFC);
- void unlockLock(const QString& lockNFC);
- public:
- static CANReturnKeyDevices returnDevicesInfo;
- private:
- bool m_threadstatus = true; // 线程运行状态标志
- mutable QMutex m_mutex; // 线程安全锁(mutable允许const函数修改)
- mutable QMutex m_frameNodeIdMutex;
- QCanBusDevice* m_CanDevice = nullptr;// CAN设备实例
- QStringList m_canBusPlugins; // CANBus插件列表(修正拼写错误)
- QList<QCanBusDeviceInfo> m_canBusInterfaces; // 可用CAN设备接口列表
- QList<quint32> m_availableFrameId; // 可用的FrameId列表
- int m_bitrate = CAN_BITERATE_1000000;// 比特率(默认1Mbps)
- bool m_canBusStatus = false; // CAN设备连接状态
- QString m_pluginsName = "socketcan"; // 默认CAN插件名称(socketcan是Linux下标准插件)
- QString m_canInterfaceName = "can0"; // CAN接口名称(如can0/can1)
- QMap<quint8, quint8> m_deviceOfNodeId;
- // 请求映射:UUID -> 回调函数(用于匹配请求和响应)
- QMap<QString, CANResponseCallback> m_requestMap;
- QMutex m_requestMutex;
- QMutex m_insertDataMutex;
- QMap<quint8, CANKeyBaseStatus> m_keyBaseStatus;
- QMap<quint8, CANKeyBaseControlStatus> m_keyBaseControlStatus;
- QMap<quint8, CANKeyRFIDStatus> m_keyRFIDStatus;
- QMap<quint8, CANLockControlStatus> m_locksControlStatus;
- QMap<quint8, CANLocksControl> m_locksControl;
- QMap<quint8, CANLockRFIDStatus> m_locksRFIDStatus;
- bool m_workingKey = false; // 标记是否进入业务逻辑
- bool m_workingLocks = false;
- };
- #endif // CANCLIENT_H
|