diff --git a/src/appPowerMangerWebUI/index.html b/bin/templates/index.html similarity index 87% rename from src/appPowerMangerWebUI/index.html rename to bin/templates/index.html index 918829e..0d7ec8c 100644 --- a/src/appPowerMangerWebUI/index.html +++ b/bin/templates/index.html @@ -138,14 +138,52 @@ .state-machine-panel { grid-column: 2; grid-row: 4; + display: flex; + flex-direction: column; + gap: 15px; + min-height: 400px; + max-height: 600px; } - pre { + .state-machine-panel h2 { + display: flex; + align-items: center; + gap: 8px; + } + + .state-machine-panel h2::before { + content: ''; + display: inline-block; + width: 12px; + height: 12px; + border-radius: 50%; + background: #61dafb; + box-shadow: 0 0 8px #61dafb; + } + + .state-machine-panel pre { margin: 0; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 1.4; + background-color: #3a3f4b; + padding: 15px; + border-radius: 6px; + border-left: 4px solid #61dafb; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + } + + .state-machine-panel pre span { + display: block; + margin-bottom: 8px; + color: #61dafb; + font-weight: bold; + } + + .state-machine-panel pre span::after { + content: ':'; + margin-left: 4px; } .file-input { @@ -320,6 +358,25 @@ // 更新页面数据的函数 function updateData() { + // 获取状态机数据 + fetch('/api/state') + .then(response => response.json()) + .then(stateData => { + // 更新状态机面板 + const stateInfo = ` +更新时间 ${stateData.time} +状态ID ${stateData.state_id} +状态名称 ${stateData.state_name} +事件 ${stateData.event} +事件ID ${stateData.event_id} +故障代码 ${stateData.fault_code} +备注 ${stateData.note} +`; + document.getElementById('state-machine-state').innerHTML = stateInfo; + }) + .catch(error => console.error('Error fetching state data:', error)); + + // 获取其他系统状态 fetch('/api/status') .then(response => response.json()) .then(data => { @@ -331,11 +388,8 @@ // 更新运行日志 document.getElementById('log-data').textContent = data.logs.join('\n'); - - // 更新状态机状态 - document.getElementById('state-machine-state').textContent = JSON.stringify(data.stateMachine, null, 2); }) - .catch(error => console.error('Error fetching data:', error)); + .catch(error => console.error('Error fetching system data:', error)); } // 检查MOOS数据库连接状态 diff --git a/src/appPowerMangerWebUI/main.cpp b/src/appPowerMangerWebUI/main.cpp index 5ebeebf..692bb68 100644 --- a/src/appPowerMangerWebUI/main.cpp +++ b/src/appPowerMangerWebUI/main.cpp @@ -17,14 +17,8 @@ using namespace std; // 定义一个全局变量,用于存储状态信息 ccuState ccustate; +StateData stateData; -// 读取 HTML 文件内容 -string read_file(const string& path) { - ifstream file(path); - stringstream buffer; - buffer << file.rdbuf(); - return buffer.str(); -} int main() { crow::SimpleApp app; @@ -32,24 +26,37 @@ int main() { MOOS::MOOSAsyncCommClient moosClient; moosClient.Run("localhost", 9000, "appPowerMangerWebUI"); - // 定义路由,处理根路径的请求 - CROW_ROUTE(app, "/")([](){ - // 读取 HTML 文件 - string html_content = read_file("/home/zjk/project/H100/H100PowerManger/src/appPowerMangerWebUI/index.html"); - return html_content; + CROW_ROUTE(app, "/")([]() { + auto page = crow::mustache::load_text("index.html"); + return page; }); + // 定义路由,处理 /api/power-data 的请求 CROW_ROUTE(app, "/api/db-status") ([&db]() { crow::json::wvalue response; if (db.isDatabaseConnected("/home/zjk/project/H100/H100PowerManger/data", "power_data.db")) { response["connected"] = true; - response["database"] = db.getDBPatch(); // 替换为实际的数据库名称 + response["database"] = db.getDBPatch(); } else { response["connected"] = false; } return response; }); + CROW_ROUTE(app, "/api/state") + ([&db]() { + crow::json::wvalue response; + string time; + db.getStateData(stateData,time);//状态机的状态 + response["state_id"] = stateData.state_id; + response["state_name"] = stateData.state_name; + response["event"] = stateData.event; + response["event_id"] = stateData.event_id; + response["fault_code"] = stateData.fault_code; + response["note"] = stateData.note; + response["time"] = time; + return response; + }); // 定义路由,处理 /api/power-data 的请求 CROW_ROUTE(app, "/api/download-db") ([&db]() { diff --git a/src/pPowerManger/SQLiteDB.cpp b/src/pPowerManger/SQLiteDB.cpp index e1aa135..bdc32e3 100644 --- a/src/pPowerManger/SQLiteDB.cpp +++ b/src/pPowerManger/SQLiteDB.cpp @@ -550,27 +550,98 @@ bool SQLiteDB::insertStateData(StateData stateData,bool filter) { } bool SQLiteDB::getStateData(StateData &stateData) { - if (!m_db) return false; + if (!m_db) { + std::cerr << "Database not initialized" << std::endl; + return false; + } const char* sql = "SELECT * FROM state_data ORDER BY timestamp DESC LIMIT 1;"; - sqlite3_stmt* stmt; + sqlite3_stmt* stmt = nullptr; + bool result = false; - if (sqlite3_prepare_v2(m_db, sql, -1, &stmt, nullptr) == SQLITE_OK) { - if (sqlite3_step(stmt) == SQLITE_ROW) { + try { + if (sqlite3_prepare_v2(m_db, sql, -1, &stmt, nullptr) != SQLITE_OK) { + throw std::runtime_error(sqlite3_errmsg(m_db)); + } + + int stepResult = sqlite3_step(stmt); + if (stepResult == SQLITE_ROW) { stateData.state_id = sqlite3_column_int(stmt, 1); - stateData.state_name = reinterpret_cast(sqlite3_column_text(stmt, 3)); - stateData.event = reinterpret_cast(sqlite3_column_text(stmt, 4)); + + const char* stateName = reinterpret_cast(sqlite3_column_text(stmt, 3)); + stateData.state_name = stateName ? stateName : ""; + + const char* event = reinterpret_cast(sqlite3_column_text(stmt, 4)); + stateData.event = event ? event : ""; + stateData.event_id = sqlite3_column_int(stmt, 5); stateData.fault_code = sqlite3_column_int(stmt, 6); - stateData.note = reinterpret_cast(sqlite3_column_text(stmt, 7)); - sqlite3_finalize(stmt); - return true; + + const char* note = reinterpret_cast(sqlite3_column_text(stmt, 7)); + stateData.note = note ? note : ""; + + result = true; + } else if (stepResult != SQLITE_DONE) { + throw std::runtime_error(sqlite3_errmsg(m_db)); } - sqlite3_finalize(stmt); - } else { - std::cerr << "Error preparing statement: " << sqlite3_errmsg(m_db) << std::endl; + } catch (const std::exception& e) { + std::cerr << "Error retrieving state data: " << e.what() << std::endl; } - return false; + + if (stmt) { + sqlite3_finalize(stmt); + } + + return result; +} + +bool SQLiteDB::getStateData(StateData &stateData, string &time) { + if (!m_db) { + std::cerr << "Database not initialized" << std::endl; + return false; + } + + const char* sql = "SELECT * FROM state_data ORDER BY timestamp DESC LIMIT 1;"; + sqlite3_stmt* stmt = nullptr; + bool result = false; + + try { + if (sqlite3_prepare_v2(m_db, sql, -1, &stmt, nullptr) != SQLITE_OK) { + throw std::runtime_error(sqlite3_errmsg(m_db)); + } + + int stepResult = sqlite3_step(stmt); + if (stepResult == SQLITE_ROW) { + stateData.state_id = sqlite3_column_int(stmt, 1); + + const char* timestamp = reinterpret_cast(sqlite3_column_text(stmt, 2)); + time = timestamp ? timestamp : ""; + + const char* stateName = reinterpret_cast(sqlite3_column_text(stmt, 3)); + stateData.state_name = stateName ? stateName : ""; + + const char* event = reinterpret_cast(sqlite3_column_text(stmt, 4)); + stateData.event = event ? event : ""; + + stateData.event_id = sqlite3_column_int(stmt, 5); + stateData.fault_code = sqlite3_column_int(stmt, 6); + + const char* note = reinterpret_cast(sqlite3_column_text(stmt, 7)); + stateData.note = note ? note : ""; + + result = true; + } else if (stepResult != SQLITE_DONE) { + throw std::runtime_error(sqlite3_errmsg(m_db)); + } + } catch (const std::exception& e) { + std::cerr << "Error retrieving state data: " << e.what() << std::endl; + } + + if (stmt) { + sqlite3_finalize(stmt); + } + + return result; } bool SQLiteDB::isDatabaseConnected(const std::string& path, const std::string& dbName) { diff --git a/src/pPowerManger/SQLiteDB.h b/src/pPowerManger/SQLiteDB.h index 38ff49e..69342a5 100644 --- a/src/pPowerManger/SQLiteDB.h +++ b/src/pPowerManger/SQLiteDB.h @@ -9,6 +9,7 @@ #include "pmSysvariable.h" #include "driver.h" + using namespace std; struct PowerData { double voltage; @@ -26,13 +27,6 @@ struct StateData { std::string note; }; -// 前向声明 -// struct ccuState; -// struct disHighVolBusState; -// struct disHighAVolBusState; -// struct disHighBVolBusState; -// struct disLowBusState; - class SQLiteDB { public: SQLiteDB(const std::string& dbPath); @@ -76,6 +70,7 @@ public: // 获取最新的状态数据 bool getStateData(StateData &stateData); + bool getStateData(StateData &stateData,string &time); // 使用函数 bool isDatabaseConnected(const std::string& path, const std::string& dbName); diff --git a/test/SQLiteDBTest.cpp b/test/SQLiteDBTest.cpp index 08e4b44..5ad8f04 100644 --- a/test/SQLiteDBTest.cpp +++ b/test/SQLiteDBTest.cpp @@ -49,6 +49,17 @@ TEST_CASE("SQLiteDB Test", "[SQLiteDB]") { } } + + SECTION("Test GETDATA") { + StateData stateData; + std::string time; + REQUIRE(db.getStateData(stateData,time) == true); + REQUIRE(db.getStateData(stateData) == true); + REQUIRE(stateData.state_id == 1); + REQUIRE(stateData.state_name == "test"); + cout << "-------------------------------------------------" << time << endl; + + } }