#ifndef PELOAD_DB_STORE_H #define PELOAD_DB_STORE_H #include #include #include struct sqlite3; struct sqlite3_stmt; namespace eload { //============================================================================ // DbStore:pELoad SQLite 存储(复用仓库内 sqlite3.c)。 // // eload_log:运行状态低频快照(1Hz),含连接/输出/模式/限值等状态; // meas_log :高采样测量记录(默认每控制周期 100ms 一条), // 实测电压/电流/功率 + 指令电流/目标功率 —— 供功率波形分析; // scpi_log :非常规 SCPI 收发记录(设定/控制/识别/错误查询等, // 例行的 MEAS 测量轮询不落库,防止表无限膨胀)。 // log_keep_hours 对三张表统一做历史清理。 //============================================================================ struct ELoadLogRow { long long id; long long time; int connected; int outp; std::string mode; // follow / manual / current / volt double targetPower; // 目标功率 W(volt 模式为 0) double voltSet; // 目标电压 V(volt 模式) double cmdCurrent; // 指令电流 A double cmdVolt; // 指令电压 V(volt 模式) double measVoltage; // 实测电压 V double measCurrent; // 实测电流 A double measPower; // 实测功率 W std::string funcMode; // CURR / VOLT long long txCount; long long rxCount; long long txErr; }; // 高采样测量记录(meas_log) struct MeasRow { long long id; double time; // unix 时间(秒,带小数) double measVoltage; double measCurrent; double measPower; double cmdCurrent; double cmdVolt; double targetPower; int outp; }; class DbStore { 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; } // 运行状态快照落库(控制线程周期调用) void insertStatus(bool connected, bool outp, const std::string& mode, double targetPower, double voltSet, double cmdCurrent, double cmdVolt, double measV, double measI, double measP, const std::string& funcMode, unsigned long tx, unsigned long rx, unsigned long txErr); // 高采样测量落库(每个控制周期调用,meas_log) void insertMeas(double measV, double measI, double measP, double cmdCurrent, double cmdVolt, double targetPower, bool outp); // SCPI 非常规收发落库:text 为 "CMD" 或 "CMD => RESP"(已配对) // direction: 1=命令 0=查询应答 void insertScpi(int direction, const std::string& text); // 历史查询(网页展示) std::vector queryRecentStatus(int limit); // 测量查询:limit 条最近记录(倒序);或指定时间范围(unix 秒) std::vector queryMeas(int limit); std::vector queryMeasRange(double startSec, double endSec, int maxRows); struct ScpiRow { long long id; long long time; int direction; std::string text; }; std::vector queryRecentScpi(int limit); long long countStatus() const; long long countScpi() const; long long countMeas() const; // 历史清理:删除 time < cutoff 的记录,返回删除行数(<0 表示出错) long long pruneOlderThan(long long cutoff); private: bool exec(const char* sql); bool ensureColumn(const std::string& table, const std::string& col, const std::string& type); bool prepareInsert(); bool prepareMeasInsert(); bool prepareScpiInsert(); std::string m_dbPath; sqlite3* m_db = nullptr; sqlite3_stmt* m_stmtInsert = nullptr; sqlite3_stmt* m_stmtMeasInsert = nullptr; sqlite3_stmt* m_stmtScpiInsert = nullptr; mutable std::mutex m_mutex; std::string m_lastError; }; } // namespace eload #endif // PELOAD_DB_STORE_H