#ifndef PCCU_DB_STORE_H #define PCCU_DB_STORE_H #include #include #include #include #include "../comm/LinkManager.h" #include "../protocol/CanBms.h" struct sqlite3; struct sqlite3_stmt; namespace ccu { //============================================================================ // DbStore:SQLite 存储。 // // 设计要点(应对协议变更): // - 以“原始帧日志”为主表(comm_log),收发全部数据按帧落库, // 协议字段变化不会导致建表失败。 // - 提供按 link / direction / msg_id 的查询接口供网页展示。 // - 锂电池 BMS/CAN 协议字段固定,另设解析数据表 bcu_node: // 每收到一帧 BMS 报文,把该 BCU 节点的合成状态落一行 // (电压/电流/SOC/单体电压温度/继电器/绝缘/告警位)。 // 复用仓库内 src/pPowerManger/sqlit3/sqlite3.c 与 sqlite3.h。 //============================================================================ struct CommLogRow { long long id; double time; std::string link; // fc / pm int direction; // 0=收 1=发 uint16_t msgId; std::string msgName; int length; int checksumOk; std::string hex; }; class DbStore : public ILinkLogSink { public: explicit DbStore(const std::string& dbPath); ~DbStore(); bool open(); void close(); bool isOpen() const { return m_db != nullptr; } std::string lastError() const { return m_lastError; } // 实现 ILinkLogSink:原始帧落库(收发双向) void onRawFrame(int direction, uint16_t msgId, const std::string& link, const std::vector& data, bool checksumOk) override; // 锂电池解析数据落库(bcu_node 表):addr=节点地址(1~54), // func=本次触发落库的 BCU 报文功能码,v=合并后的节点最新状态 void insertBcuNode(uint8_t addr, uint8_t func, const BcuNodeStatus& v); // 查询最近 N 条记录(可限定链路/方向/消息id;limit<=0 表示默认 100) std::vector queryRecent(const std::string& link, int direction, uint16_t msgId, int limit); long long count() const; long long countBcu() const; private: bool exec(const char* sql); bool prepareInsert(); bool prepareBcuInsert(); std::string m_dbPath; sqlite3* m_db = nullptr; sqlite3_stmt* m_stmtInsert = nullptr; sqlite3_stmt* m_stmtBcuInsert = nullptr; mutable std::mutex m_mutex; std::string m_lastError; }; } // namespace ccu #endif // PCCU_DB_STORE_H