优化了主页的读取方式
This commit is contained in:
@@ -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 = `
|
||||
<span>更新时间</span> ${stateData.time}
|
||||
<span>状态ID</span> ${stateData.state_id}
|
||||
<span>状态名称</span> ${stateData.state_name}
|
||||
<span>事件</span> ${stateData.event}
|
||||
<span>事件ID</span> ${stateData.event_id}
|
||||
<span>故障代码</span> ${stateData.fault_code}
|
||||
<span>备注</span> ${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数据库连接状态
|
||||
@@ -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]() {
|
||||
|
||||
@@ -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<const char*>(sqlite3_column_text(stmt, 3));
|
||||
stateData.event = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4));
|
||||
|
||||
const char* stateName = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
|
||||
stateData.state_name = stateName ? stateName : "";
|
||||
|
||||
const char* event = reinterpret_cast<const char*>(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<const char*>(sqlite3_column_text(stmt, 7));
|
||||
sqlite3_finalize(stmt);
|
||||
return true;
|
||||
|
||||
const char* note = reinterpret_cast<const char*>(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<const char*>(sqlite3_column_text(stmt, 2));
|
||||
time = timestamp ? timestamp : "";
|
||||
|
||||
const char* stateName = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
|
||||
stateData.state_name = stateName ? stateName : "";
|
||||
|
||||
const char* event = reinterpret_cast<const char*>(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<const char*>(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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user