CANClient.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #ifndef CANCLIENT_H
  2. #define CANCLIENT_H
  3. #include <QThread>
  4. #include <QCanBusDevice>
  5. #include <QCanBus>
  6. #include <QMap>
  7. #include <QList>
  8. #include <QMutex>
  9. #include <QString>
  10. #include <QByteArray>
  11. #include <QTimer>
  12. #include <QtQml/qqml.h>
  13. #include "define.h"
  14. #define CAN_SLEEP_TIME 50
  15. // 响应回调函数类型定义
  16. using CANResponseCallback = std::function<void(const QCanBusFrame& respFrame)>;
  17. typedef struct {
  18. bool success = false; // 读取是否成功
  19. quint8 nodeId = 0;
  20. bool leftHasKey = false; // 左钥匙是否存在
  21. bool leftCharging = false; // 左钥匙是否充电中
  22. bool rightHasKey = false; // 右钥匙是否存在
  23. bool rightCharging = false; // 右钥匙是否充电中
  24. } CANKeyBaseStatus;
  25. Q_DECLARE_METATYPE(CANKeyBaseStatus)
  26. typedef struct {
  27. bool success = false; // 读取是否成功
  28. quint8 nodeId = 0;
  29. bool leftLocked = false; // 左钥匙是否锁住
  30. bool leftCharging = false; // 左钥匙是否充电中
  31. bool rightLocked = false; // 右钥匙是否锁住
  32. bool rightCharging = false; // 右钥匙是否充电中
  33. bool leftBuckleFault = false; // 左卡扣故障
  34. bool rightBuckleFault = false; // 右卡扣故障
  35. } CANKeyBaseControlStatus;
  36. Q_DECLARE_METATYPE(CANKeyBaseControlStatus)
  37. typedef struct {
  38. bool success = false; // 读取是否成功
  39. quint8 nodeId = 0;
  40. QList<int> lockNums;
  41. QMap<int, bool> lockHasKeyMap; // 1-5号锁有锁/无锁(索引0=1号锁)
  42. QMap<int, bool> lockFaultMap; // 锁故障状态(key=锁号)
  43. } CANLockControlStatus;
  44. Q_DECLARE_METATYPE(CANLockControlStatus)
  45. typedef struct {
  46. int lockNum = 0; // 锁号1-5
  47. quint8 nodeId = 0;
  48. bool isWorking = false; // 设置工作状态
  49. bool isLocked = false; // 设置锁定状态
  50. } CANSingleLockStatus;
  51. Q_DECLARE_METATYPE(CANSingleLockStatus)
  52. typedef struct {
  53. bool success = false;
  54. quint8 nodeId = 0;
  55. QList<int> lockNums;
  56. QMap<int, bool> lockWorkMap; // 设置工作状态(key=锁号)
  57. QMap<int, bool> lockLockedMap; // 设置锁定状态(key=锁号)
  58. } CANLocksControl;
  59. Q_DECLARE_METATYPE(CANLocksControl)
  60. typedef struct {
  61. bool success = false; // 读取是否成功
  62. quint8 nodeId = 0;
  63. QString leftKeyRFID; // 左钥匙卡号
  64. QString rightKeyRFID; // 右钥匙卡号
  65. bool leftKeyReadSuccess = false; // 左钥匙单独读取成功标记
  66. bool rightKeyReadSuccess = false; // 右钥匙单独读取成功标记
  67. } CANKeyRFIDStatus;
  68. Q_DECLARE_METATYPE(CANKeyRFIDStatus)
  69. typedef struct {
  70. bool success = false; // 读取是否成功
  71. quint8 nodeId = 0;
  72. QMap<int, QString> lockRFIDMap; // 各锁卡号(key=锁号)
  73. QMap<int, bool> lockReadSuccessMap; // 各锁读取成功标记(key=锁号)
  74. } CANLockRFIDStatus;
  75. Q_DECLARE_METATYPE(CANLockRFIDStatus)
  76. enum class ChargeState {
  77. Uncharged = 0, // 未充电
  78. Charging = 1, // 充电中
  79. };
  80. typedef struct {
  81. bool success = false; // 读取/写入是否成功
  82. quint8 nodeId = 0;
  83. // 可写控制项(仅充电使能)
  84. bool leftChargeEnable = false;// 左卡扣充电使能(1=开启,0=关闭)
  85. bool rightChargeEnable = false;// 右卡扣充电使能
  86. // 只读状态项(设备反馈)
  87. bool leftLocked = false; // 左卡扣上锁状态(1=上锁)
  88. bool rightLocked = false; // 右卡扣上锁状态
  89. bool leftWorking = false; // 左卡扣工作状态(1=工作中)
  90. bool rightWorking = false; // 右卡扣工作状态
  91. ChargeState leftChargeState = ChargeState::Uncharged; // 左卡扣充电细分状态
  92. ChargeState rightChargeState = ChargeState::Uncharged; // 右卡扣充电细分状态
  93. } CANKeyBaseChargeStatus;
  94. Q_DECLARE_METATYPE(CANKeyBaseChargeStatus)
  95. typedef struct {
  96. QMap<QString, quint8> keysMap;
  97. QMap<QString, quint8> locksMap;
  98. } CANReturnKeyDevices;
  99. Q_DECLARE_METATYPE(CANReturnKeyDevices)
  100. class CANClient : public QThread
  101. {
  102. Q_OBJECT
  103. QML_NAMED_ELEMENT(CANClient)
  104. Q_PROPERTY(bool workingKey READ workingKey WRITE setWorkingKey NOTIFY workingKeyChanged)
  105. Q_PROPERTY(bool workingLocks READ workingLocks WRITE setWorkingLocks NOTIFY workingLocksChanged)
  106. public:
  107. explicit CANClient(QObject *parent = nullptr);
  108. ~CANClient() override; // 补充析构函数,释放资源
  109. /* 连接或者断开 CAN 设备 */
  110. void connectDevice();
  111. /* 获取当前CAN设备连接状态 */
  112. bool isCanBusConnected() const { return m_canBusStatus; }
  113. // 异步发送CAN帧,通过回调返回响应
  114. void sendFrameAsync(const QCanBusFrame& frame, CANResponseCallback callback);
  115. void testFunc();
  116. QString getLockRFID(int lockNum);
  117. bool workingKey() const {
  118. return m_workingKey;
  119. }
  120. void setWorkingKey(bool isWorking) {
  121. m_workingKey = isWorking;
  122. emit workingKeyChanged();
  123. }
  124. bool workingLocks() const {
  125. return m_workingLocks;
  126. }
  127. void setWorkingLocks(bool isWorking) {
  128. m_workingLocks = isWorking;
  129. emit workingLocksChanged();
  130. }
  131. protected:
  132. void run() override;
  133. private:
  134. /* 初始化CAN总线插件列表 */
  135. void pluginItemInit();
  136. /* 初始化比特率和CAN设备实例 */
  137. void bitrateItemInit();
  138. public:
  139. /* 安全停止线程并释放资源 */
  140. void stopThreadAndRelease();
  141. QMap<quint8, CANKeyRFIDStatus> keyRFIDStatus() const {
  142. return m_keyRFIDStatus;
  143. }
  144. QMap<quint8, CANKeyBaseStatus> keyBaseStatus() const {
  145. return m_keyBaseStatus;
  146. }
  147. private slots:
  148. /* 接收CAN总线消息帧 */
  149. void receivedFrames();
  150. /* 处理CAN设备错误 */
  151. void canDeviceErrors(QCanBusDevice::CanBusError error) const;
  152. void slotUpdateKeyBaseStatus(quint8 nodeId, const CANKeyBaseStatus& status);
  153. // 根据读取到钥匙的状态(有/无钥匙和是否锁住)更新
  154. void slotUpdateKeyBaseControl(quint8 nodeId, const CANKeyBaseControlStatus& status);
  155. // 根据读取到5路锁的状态(有/无锁和是否锁住)更新
  156. void slotUpdateLockedStatus(quint8 nodeId, const CANLocksControl& status);
  157. void slotWorkingKeyChanged();
  158. void slotWorkingLocksChanged();
  159. signals:
  160. // 设备类型信息读取完成
  161. void deviceInfoRead(bool success, const quint8& nodeId);
  162. // 钥匙底座状态读取完成
  163. void keyBaseStatusRead(quint8 nodeId, const CANKeyBaseStatus& status);
  164. void keyBaseControlStatusRead(quint8 nodeId, const CANKeyBaseControlStatus& status);
  165. // 5路锁状态读取完成
  166. void lockStatusRead(quint8 nodeId, const CANLockControlStatus& lockHasKeyList);
  167. void lockControlStatusRead(quint8 nodeId, const CANLocksControl& status);
  168. void lockBuckleWritten(bool success, const QList<QString>& lockNfc);
  169. // 锁扣控制完成
  170. void lockBuckleWrite(bool success, int lockNum, bool isLock);
  171. // 温湿度读取完成
  172. void temperatureRead(bool success, double leftTemp, double rightTemp);
  173. void humidityRead(bool success, double humidity);
  174. // CAN设备连接状态变化
  175. void signalCanBusStatusChanged(bool isConnected);
  176. void keyRFIDStatusRead(quint8 nodeId, const CANKeyRFIDStatus& status); // 钥匙RFID读取完成
  177. void lockRFIDStatusRead(quint8 nodeId, const CANLockRFIDStatus& status); // 锁RFID读取完成
  178. void singleKeyRFIDRead(bool isLeftKey, bool success, const QString& rfidCard); // 单个钥匙RFID
  179. void singleLockRFIDRead(int lockNum, bool success, const QString& rfidCard); // 单个锁RFID
  180. void keyBaseChargeControlWritten(const CANKeyBaseChargeStatus& status);
  181. void singleKeyBaseChargeControlWritten(bool isLeftKey, bool success,
  182. bool chargeEnable, bool locked,
  183. bool working, ChargeState chargeState);
  184. void keyBaseChargeStatusRead(const CANKeyBaseChargeStatus& status);
  185. void workingKeyChanged();
  186. void workingLocksChanged();
  187. // ========== 归还钥匙和锁检测信号 ==========
  188. // 当检测到NFC设备插入时发出(用于归还流程)
  189. void nfcDeviceDetected(const QString& nfcId, const QString& deviceType, int slotIndex);
  190. void signalLockNfcDeviceDetected(const QString& nfcId);
  191. // 当检测到设备异常时发出(无法读取NFC)
  192. void nfcDeviceError(const QString& deviceType, int slotIndex);
  193. // ==========================================
  194. void signalReturnKey();
  195. void signalPopDevices(const QString& nfcId, const QString& deviceType, int slotIndex);
  196. private:
  197. // 处理设备主动上报的插入帧(归还流程)
  198. void handleDeviceInsertionFrame(const QCanBusFrame& frame);
  199. // 构造SDO读报文
  200. QCanBusFrame buildReadFrame(quint8 nodeId, quint16 index, quint8 subIndex);
  201. // 构造SDO写报文
  202. QCanBusFrame buildWriteFrame(quint8 nodeId, quint16 index, quint8 subIndex, const QByteArray& data, quint8 byteCount = 0);
  203. // 解析小端数据(16位)
  204. quint16 parseLittleEndian16(const QByteArray& data);
  205. // 解析小端数据(32位)
  206. quint32 parseLittleEndian32(const QByteArray& data);
  207. // 解析温度数据(有符号16位/10)
  208. double parseTemperature(const QByteArray& data);
  209. // 解析湿度数据(无符号16位/10)
  210. double parseHumidity(const QByteArray& data);
  211. // 解析RFID卡号(小端4字节)
  212. QString parseRFIDCard(const QByteArray& data);
  213. // bool verifyNodeID(quint8 deviceNodeId, quint8& returnNodeId);
  214. bool verifyAllNodeID(quint8 deviceNodeId, QList<quint8>& returnNodeId);
  215. ChargeState bitToChargeState(uint8_t bitValue) {
  216. switch (bitValue) {
  217. case 0: return ChargeState::Uncharged;
  218. case 1: return ChargeState::Charging;
  219. default: return ChargeState::Uncharged;
  220. }
  221. }
  222. QString chargeStateToString(ChargeState state) {
  223. switch (state) {
  224. case ChargeState::Uncharged: return "未充电";
  225. case ChargeState::Charging: return "充电中";
  226. default: return "未充电";
  227. }
  228. }
  229. private:
  230. // 检查锁扣编号有效性(1-5号)
  231. bool checkLockNumValid(int lockNum);
  232. // 检查RGB通道有效性(1-4路)
  233. bool checkRGBChannelValid(int channel);
  234. // 检查亮度值有效性(0-100)
  235. bool checkBrightnessValid(int bright);
  236. //
  237. void readDeviceInfoAsync(quint8 nodeId);
  238. // 电子钥匙底座
  239. void readAllKeyBaseStatusAsync();
  240. void readKeyBaseStatusAsync(quint8 nodeId);
  241. void readAllKeyBaseControlStatusAsync();
  242. void readKeyBaseControlStatusAsync(quint8 nodeId);
  243. // 5路挂锁底座
  244. void readAllLocksStatusAsync();
  245. void readLockStatusAsync(quint8 nodeId);
  246. void readAllLocksControlStatusAsync();
  247. void readLockControlStatusAsync(quint8 nodeId);
  248. void writeSingleLockBuckleAsync(const CANSingleLockStatus& status);
  249. void writeLockBuckleAsync(const CANLocksControl& status);
  250. // 温湿度
  251. void readTemperatureAsync(quint8 nodeId);
  252. // 批量读取:仅左+右钥匙
  253. void readAllKeyRFIDStatusAsync();
  254. void readKeyRFIDStatusAsync(quint8 nodeId);
  255. // 批量读取:仅1-5号锁
  256. void readAllLocksRFIDStatusAsync();
  257. void readLockRFIDStatusAsync(quint8 nodeId);
  258. // 单个读取:仅左/右钥匙
  259. void readSingleKeyRFIDAsync(quint8 nodeId, bool isLeftKey);
  260. // 单个读取:仅某一个锁
  261. void readSingleLockRFIDAsync(quint8 nodeId, int lockNum);
  262. // 左+右卡扣充电使能
  263. void writeKeyBaseChargeControlAsync(CANKeyBaseChargeStatus& chargeStatus);
  264. // 读取卡扣当前充电状态
  265. void readKeyBaseChargeStatusAsync(quint8 nodeId);
  266. public:
  267. bool openEKey(QString& keyNFC);
  268. bool unlockEKey();
  269. bool getLockRfids(int lockCount, QMap<int, QString>& rfids);
  270. bool unlockLocks(const QList<int>& lockNums);
  271. void unlockEKey(const QString& keyNFC);
  272. void unlockLock(const QString& lockNFC);
  273. public:
  274. static CANReturnKeyDevices returnDevicesInfo;
  275. private:
  276. bool m_threadstatus = true; // 线程运行状态标志
  277. mutable QMutex m_mutex; // 线程安全锁(mutable允许const函数修改)
  278. mutable QMutex m_frameNodeIdMutex;
  279. QCanBusDevice* m_CanDevice = nullptr;// CAN设备实例
  280. QStringList m_canBusPlugins; // CANBus插件列表(修正拼写错误)
  281. QList<QCanBusDeviceInfo> m_canBusInterfaces; // 可用CAN设备接口列表
  282. QList<quint32> m_availableFrameId; // 可用的FrameId列表
  283. int m_bitrate = CAN_BITERATE_1000000;// 比特率(默认1Mbps)
  284. bool m_canBusStatus = false; // CAN设备连接状态
  285. QString m_pluginsName = "socketcan"; // 默认CAN插件名称(socketcan是Linux下标准插件)
  286. QString m_canInterfaceName = "can0"; // CAN接口名称(如can0/can1)
  287. QMap<quint8, quint8> m_deviceOfNodeId;
  288. // 请求映射:UUID -> 回调函数(用于匹配请求和响应)
  289. QMap<QString, CANResponseCallback> m_requestMap;
  290. QMutex m_requestMutex;
  291. QMutex m_insertDataMutex;
  292. QMap<quint8, CANKeyBaseStatus> m_keyBaseStatus;
  293. QMap<quint8, CANKeyBaseControlStatus> m_keyBaseControlStatus;
  294. QMap<quint8, CANKeyRFIDStatus> m_keyRFIDStatus;
  295. QMap<quint8, CANLockControlStatus> m_locksControlStatus;
  296. QMap<quint8, CANLocksControl> m_locksControl;
  297. QMap<quint8, CANLockRFIDStatus> m_locksRFIDStatus;
  298. bool m_workingKey = false; // 标记是否进入业务逻辑
  299. bool m_workingLocks = false;
  300. };
  301. #endif // CANCLIENT_H