优化了主页的读取方式

This commit is contained in:
zjk
2025-02-27 10:00:42 +08:00
parent 4ee5cbfb86
commit 115ee57b14
5 changed files with 176 additions and 38 deletions
-436
View File
@@ -1,436 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电源管理</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
/* 全局样式 */
body {
font-family: 'Arial', sans-serif;
background-color: #282c34;
color: #ffffff;
margin: 0;
padding: 20px;
height: 100vh;
display: grid;
grid-template-rows: auto auto 1fr 1fr;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.db-status-panel {
grid-column: 1 / -1;
background-color: #333;
border: 1px solid #61dafb;
border-radius: 8px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.control-panel {
grid-column: 1 / -1;
display: flex;
gap: 20px;
padding: 20px;
background-color: #333;
border: 1px solid #61dafb;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.db-status {
display: flex;
align-items: center;
gap: 10px;
font-size: 16px;
}
.db-status i {
font-size: 20px;
}
.db-status.connected {
color: #4caf50;
}
.db-status.disconnected {
color: #f44336;
}
.control-panel button {
flex: 1;
padding: 15px 20px;
background: linear-gradient(145deg, #61dafb, #4fa8c7);
border: none;
border-radius: 6px;
color: #282c34;
cursor: pointer;
font-weight: bold;
font-size: 14px;
text-align: left;
display: flex;
align-items: center;
gap: 10px;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.control-panel button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
background: linear-gradient(145deg, #4fa8c7, #61dafb);
}
.control-panel button i {
font-size: 18px;
}
.panel {
background-color: #333;
border: 1px solid #61dafb;
border-radius: 8px;
padding: 20px;
overflow: auto;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.panel h2 {
color: #61dafb;
margin-top: 0;
margin-bottom: 15px;
font-size: 18px;
}
.status-columns {
display: flex;
gap: 20px;
}
.status-column {
flex: 1;
}
.status-column h3 {
color: #61dafb;
margin-top: 0;
margin-bottom: 10px;
font-size: 14px;
}
.log-panel {
grid-column: 1;
grid-row: 4;
}
.ccu-state-panel {
grid-column: 2;
grid-row: 3;
}
.dis-sys-panel {
grid-column: 1;
grid-row: 3;
}
.state-machine-panel {
grid-column: 2;
grid-row: 4;
}
pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
font-size: 13px;
line-height: 1.4;
}
.file-input {
display: none;
}
.file-label {
display: inline-block;
padding: 10px 15px;
background: #61dafb;
color: #282c34;
border-radius: 4px;
cursor: pointer;
margin-left: 10px;
}
/* MOOS通知面板样式 */
.moos-notify-panel {
margin-top: 20px;
padding: 15px;
background-color: #3a3f4b;
border: 1px solid #61dafb;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.moos-notify-panel .input-group {
margin-bottom: 15px;
}
.moos-notify-panel label {
display: block;
margin-bottom: 5px;
color: #61dafb;
font-size: 14px;
}
.moos-notify-panel input {
width: 80%;
padding: 8px 8px;
background-color: #282c34;
border: 1px solid #61dafb;
border-radius: 4px;
color: #ffffff;
font-size: 14px;
}
.moos-notify-panel input:focus {
outline: none;
border-color: #4fa8c7;
box-shadow: 0 0 0 2px rgba(97, 218, 251, 0.2);
}
.moos-notify-panel button {
width: 80%;
padding: 8px;
background: linear-gradient(145deg, #61dafb, #4fa8c7);
border: none;
border-radius: 4px;
color: #282c34;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
}
.moos-notify-panel button:hover {
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
</style>
</head>
<body>
<div class="db-status-panel">
<!-- <h2>连接状态</h2> -->
<div class="status-columns">
<div class="status-column">
<h3>MOOSDB</h3>
<div class="db-status" id="moos-db-status">
<i class="fas fa-database"></i>
<span>正在连接MOOSDB...</span>
</div>
<div class="moos-notify-panel">
<div class="input-group">
<label for="moos-var">Var:</label>
<input type="text" id="moos-var" placeholder="输入Var值">
</div>
<div class="input-group">
<label for="moos-key">Key:</label>
<input type="text" id="moos-key" placeholder="输入Key值">
</div>
<button id="moos-send-btn">发送</button>
</div>
</div>
<div class="status-column">
<h3>本地数据库</h3>
<div class="db-status" id="db-status">
<i class="fas fa-database"></i>
<span>正在连接数据库...</span>
</div>
</div>
</div>
</div>
<div class="control-panel">
<button id="mode-switch">
<i class="fas fa-exchange-alt"></i>
系统模式切换
</button>
<button id="condition-switch">
<i class="fas fa-cogs"></i>
系统工况切换
</button>
<button id="system-reset">
<i class="fas fa-redo"></i>
系统复位操作
</button>
<div class="control-panel">
<button id="download-db">
<i class="fas fa-download"></i>
下载数据库
</button>
</div>
</div>
<div class="panel dis-sys-panel">
<h2>DIS系统状态</h2>
<pre id="dis-sys-state">正在加载...</pre>
</div>
<div class="panel ccu-state-panel">
<h2>CCU状态</h2>
<pre id="ccu-state">正在加载...</pre>
</div>
<div class="panel log-panel">
<h2>运行日志</h2>
<pre id="log-data">正在加载...</pre>
</div>
<div class="panel state-machine-panel">
<h2>状态机状态</h2>
<pre id="state-machine-state">正在加载...</pre>
</div>
<script>
let currentDbPath = '/home/zjk/project/H100/H100PowerManger/data/power_data.db';
// 数据库下载功能
document.getElementById('download-db').addEventListener('click', function() {
fetch('/api/download-db')
.then(response => {
if (!response.ok) {
throw new Error('下载失败:' + response.statusText);
}
return response.blob();
})
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'power_data.db';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
.catch(error => {
console.error('下载数据库失败:', error);
alert('下载数据库失败:' + error.message);
});
});
// 更新页面数据的函数
function updateData() {
fetch('/api/status')
.then(response => response.json())
.then(data => {
// 更新DIS系统状态
document.getElementById('dis-sys-state').textContent = JSON.stringify(data.disSys, null, 2);
// 更新CCU状态
document.getElementById('ccu-state').textContent = JSON.stringify(data.ccuState, null, 2);
// 更新运行日志
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));
}
// 检查MOOS数据库连接状态
function checkMoosDbConnection() {
fetch('/api/moos-db')
.then(response => response.json())
.then(data => {
const moosDbStatus = document.getElementById('moos-db-status');
if (data.connected) {
moosDbStatus.className = 'db-status connected';
moosDbStatus.innerHTML = `<i class="fas fa-database"></i><span>已连接到MOOS数据库:${data.host}:${data.port}</span>`;
} else {
moosDbStatus.className = 'db-status disconnected';
moosDbStatus.innerHTML = `<i class="fas fa-database"></i><span>MOOS数据库连接失败</span>`;
}
})
.catch(error => {
const moosDbStatus = document.getElementById('moos-db-status');
moosDbStatus.className = 'db-status disconnected';
moosDbStatus.innerHTML = `<i class="fas fa-database"></i><span>MOOS数据库连接错误</span>`;
});
}
// 检查本地数据库连接状态
function checkDbConnection() {
fetch('/api/db-status')
.then(response => response.json())
.then(data => {
const dbStatus = document.getElementById('db-status');
if (data.connected) {
dbStatus.className = 'db-status connected';
dbStatus.innerHTML = `<i class="fas fa-database"></i><span>已连接到数据库:${data.database}</span>`;
} else {
dbStatus.className = 'db-status disconnected';
dbStatus.innerHTML = `<i class="fas fa-database"></i><span>数据库连接失败</span>`;
}
})
.catch(error => {
const dbStatus = document.getElementById('db-status');
dbStatus.className = 'db-status disconnected';
dbStatus.innerHTML = `<i class="fas fa-database"></i><span>数据库连接错误</span>`;
});
}
// MOOS通知功能
function sendMoosNotify() {
const varValue = document.getElementById('moos-var').value.trim();
const keyValue = document.getElementById('moos-key').value.trim();
if (!varValue || !keyValue) {
alert('请填写Var和Key值');
return;
}
const payload = {
var: varValue,
// key: isNaN(keyValue) ? keyValue : Number(keyValue)
key: keyValue
};
fetch('/api/moos-notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('发送成功');
} else {
alert('发送失败: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('发送请求失败');
});
}
document.getElementById('moos-send-btn').addEventListener('click', sendMoosNotify);
// 每1秒更新一次数据
setInterval(updateData, 1000);
updateData(); // 初始加载
// 每3秒检查一次数据库连接状态
setInterval(() => {
checkDbConnection();
checkMoosDbConnection();
}, 3000);
checkDbConnection(); // 初始检查
checkMoosDbConnection(); // 初始检查
</script>
</body>
</html>
+20 -13
View File
@@ -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]() {
+84 -13
View File
@@ -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) {
+2 -7
View File
@@ -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);