Files
H100PowerManger/src/pPowerManger/httpserver/index.h
T
2025-05-16 01:08:12 +08:00

616 lines
23 KiB
C++

#ifndef HTTP_SERVER_INDEX_H
#define HTTP_SERVER_INDEX_H
#include <string>
const std::string INDEX_HTML = R"(
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Power Manager</title>
<link rel="stylesheet" href="/static/style.css">
<style>
.data-item {
margin: 10px 0;
padding: 8px;
background: #f5f5f5;
border-radius: 4px;
}
.data-label {
font-weight: bold;
margin-right: 10px;
}
.collapsible {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 10px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
margin-top: 10px;
}
.active, .collapsible:hover {
background-color: #ccc;
}
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f9f9f9;
}
</style>
</head>
<body>
<h1>Power Manager System</h1>
<button class="collapsible">燃料电池系统状态</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">FC模式:</span>
<span class="data-value" id="fc-mode">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">FC状态:</span>
<span class="data-value" id="fc-status">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">故障等级:</span>
<span class="data-value" id="fc-fault-level">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">输出功率限制:</span>
<span class="data-value" id="output-power-limit">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">累计发电时间:</span>
<span class="data-value" id="total-generation-time">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">累计发电功率:</span>
<span class="data-value" id="total-generation-power">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">FC故障等级1:</span>
<span class="data-value" id="fc-fault-level-1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">FC故障等级2:</span>
<span class="data-value" id="fc-fault-level-2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">FC故障等级3:</span>
<span class="data-value" id="fc-fault-level-3">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">FC故障等级4:</span>
<span class="data-value" id="fc-fault-level-4">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">燃料和容量</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">氢容量:</span>
<span class="data-value" id="hydrogen-capacity">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">液氧容量:</span>
<span class="data-value" id="liquid-oxygen-capacity">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">燃料电池温度压力参数</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">钯膜温度:</span>
<span class="data-value" id="palladium-temp">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">主水路压力:</span>
<span class="data-value" id="main-pipe-pressure">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">辅水路压力:</span>
<span class="data-value" id="aux-pipe-pressure">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">锂电池舱室环境</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">仪表舱室压力:</span>
<span class="data-value" id="cabin-pressure1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力舱室压力:</span>
<span class="data-value" id="cabin-pressure2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表舱室温度:</span>
<span class="data-value" id="cabin-temp1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力舱室温度:</span>
<span class="data-value" id="cabin-temp2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表舱室湿度:</span>
<span class="data-value" id="cabin-humidity1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力舱室湿度:</span>
<span class="data-value" id="cabin-humidity2">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">燃料电池气体浓度</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">H2浓度1:</span>
<span class="data-value" id="h2-concentration1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">H2浓度2:</span>
<span class="data-value" id="h2-concentration2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">H2浓度3:</span>
<span class="data-value" id="h2-concentration3">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">O2浓度1:</span>
<span class="data-value" id="o2-concentration1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">O2浓度2:</span>
<span class="data-value" id="o2-concentration2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">甲醇浓度1:</span>
<span class="data-value" id="ch3oh-concentration1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">甲醇浓度2:</span>
<span class="data-value" id="ch3oh-concentration2">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">电池系统</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">仪表电池SOC:</span>
<span class="data-value" id="ins-soc">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力电池SOC:</span>
<span class="data-value" id="dyn-soc">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表电池电压:</span>
<span class="data-value" id="ins-voltage-link">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力电池电压:</span>
<span class="data-value" id="dyn-voltage-link">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表电池电流:</span>
<span class="data-value" id="ins-current">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力电池电流:</span>
<span class="data-value" id="dyn-current">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表电池能量:</span>
<span class="data-value" id="ins-total-energy">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力电池能量:</span>
<span class="data-value" id="dyn-total-energy">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表电池输入功率:</span>
<span class="data-value" id="ins-power-input">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力电池输入功率:</span>
<span class="data-value" id="dyn-power-input">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">继电器状态</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">仪表继电器1:</span>
<span class="data-value" id="ins-relay-status1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表继电器2:</span>
<span class="data-value" id="ins-relay-status2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力继电器1:</span>
<span class="data-value" id="dyn-relay-status1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力继电器2:</span>
<span class="data-value" id="dyn-relay-status2">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">锂电池报警标志</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">动力报警标志1:</span>
<span class="data-value" id="dyn-alarm-flag1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力报警标志2:</span>
<span class="data-value" id="dyn-alarm-flag2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力报警标志3:</span>
<span class="data-value" id="dyn-alarm-flag3">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力报警标志4:</span>
<span class="data-value" id="dyn-alarm-flag4">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力报警标志5:</span>
<span class="data-value" id="dyn-alarm-flag5">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">动力报警标志6:</span>
<span class="data-value" id="dyn-alarm-flag6">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表报警标志1:</span>
<span class="data-value" id="ins-alarm-flag1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表报警标志2:</span>
<span class="data-value" id="ins-alarm-flag2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表报警标志3:</span>
<span class="data-value" id="ins-alarm-flag3">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表报警标志4:</span>
<span class="data-value" id="ins-alarm-flag4">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表报警标志5:</span>
<span class="data-value" id="ins-alarm-flag5">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">仪表报警标志6:</span>
<span class="data-value" id="ins-alarm-flag6">正在加载...</span>
</div>
</div>
</div>
<button class="collapsible">其他系统参数</button>
<div class="content">
<div class="system-data-grid">
<div class="data-item">
<span class="data-label">设备在线标志1:</span>
<span class="data-value" id="device-online-flag1">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">设备在线标志2:</span>
<span class="data-value" id="device-online-flag2">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">心跳计数器:</span>
<span class="data-value" id="heartbeat">正在加载...</span>
</div>
<div class="data-item">
<span class="data-label">时间戳:</span>
<span class="data-value" id="timestamp">正在加载...</span>
</div>
</div>
</div>
<script>
// WebSocket连接
let ws = null;
// 初始化WebSocket连接
function initWebSocket() {
ws = new WebSocket('ws://' + window.location.host + '/ws');
ws.onopen = () => {
console.log('WebSocket连接已建立');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
updateSystemData(data);
};
ws.onclose = () => {
console.log('WebSocket连接已关闭');
setTimeout(initWebSocket, 5000); // 5秒后重连
};
ws.onerror = (error) => {
console.error('WebSocket错误:', error);
};
}
// 更新系统数据
function updateSystemData(data) {
// 燃料电池数据
if (data.fc_mode !== undefined) {
document.getElementById('fc-mode').textContent = getFCModeText(data.fc_mode);
}
if (data.fc_status !== undefined) {
document.getElementById('fc-status').textContent = getFCStatusText(data.fc_status);
}
if (data.fc_fault_level !== undefined) {
document.getElementById('fc-fault-level').textContent = data.fc_fault_level;
}
if (data.output_power_limit !== undefined) {
document.getElementById('output-power-limit').textContent = data.output_power_limit + ' W';
}
if (data.total_generation_time !== undefined) {
document.getElementById('total-generation-time').textContent = (data.total_generation_time).toFixed(1) + ' 小时';
}
if (data.total_generation_power !== undefined) {
document.getElementById('total-generation-power').textContent = data.total_generation_power + ' W';
}
if (data.fc_fault_level_1 !== undefined) {
document.getElementById('fc-fault-level-1').textContent = data.fc_fault_level_1;
}
if (data.fc_fault_level_2 !== undefined) {
document.getElementById('fc-fault-level-2').textContent = data.fc_fault_level_2;
}
if (data.fc_fault_level_3 !== undefined) {
document.getElementById('fc-fault-level-3').textContent = data.fc_fault_level_3;
}
if (data.fc_fault_level_4 !== undefined) {
document.getElementById('fc-fault-level-4').textContent = data.fc_fault_level_4;
}
// 燃料容量
if (data.hydrogen_capacity !== undefined) {
document.getElementById('hydrogen-capacity').textContent = data.hydrogen_capacity + '%';
}
if (data.liquid_oxygen_capacity !== undefined) {
document.getElementById('liquid-oxygen-capacity').textContent = data.liquid_oxygen_capacity + '%';
}
// 温度压力参数
if (data.palladium_temp !== undefined) {
document.getElementById('palladium-temp').textContent = data.palladium_temp + ' ℃';
}
if (data.main_pipe_pressure !== undefined) {
document.getElementById('main-pipe-pressure').textContent = (data.main_pipe_pressure).toFixed(2) + ' kPa';
}
if (data.aux_pipe_pressure !== undefined) {
document.getElementById('aux-pipe-pressure').textContent = (data.aux_pipe_pressure).toFixed(2) + ' kPa';
}
// 舱室环境
if (data.cabin_pressure1 !== undefined) {
document.getElementById('cabin-pressure1').textContent = (data.cabin_pressure1).toFixed(2) + ' kPa';
}
if (data.cabin_pressure2 !== undefined) {
document.getElementById('cabin-pressure2').textContent = (data.cabin_pressure2).toFixed(2) + ' kPa';
}
if (data.cabin_temp1 !== undefined) {
document.getElementById('cabin-temp1').textContent = data.cabin_temp1 + ' ℃';
}
if (data.cabin_temp2 !== undefined) {
document.getElementById('cabin-temp2').textContent = data.cabin_temp2 + ' ℃';
}
if (data.cabin_humidity1 !== undefined) {
document.getElementById('cabin-humidity1').textContent = data.cabin_humidity1 + '%';
}
if (data.cabin_humidity2 !== undefined) {
document.getElementById('cabin-humidity2').textContent = data.cabin_humidity2 + '%';
}
// 气体浓度
if (data.h2_concentration1 !== undefined) {
document.getElementById('h2-concentration1').textContent = data.h2_concentration1 + ' ppm';
}
if (data.h2_concentration2 !== undefined) {
document.getElementById('h2-concentration2').textContent = data.h2_concentration2 + ' ppm';
}
if (data.h2_concentration3 !== undefined) {
document.getElementById('h2-concentration3').textContent = data.h2_concentration3 + ' ppm';
}
if (data.o2_concentration1 !== undefined) {
document.getElementById('o2-concentration1').textContent = data.o2_concentration1 + ' ppm';
}
if (data.o2_concentration2 !== undefined) {
document.getElementById('o2-concentration2').textContent = data.o2_concentration2 + ' ppm';
}
if (data.ch3oh_concentration1 !== undefined) {
document.getElementById('ch3oh-concentration1').textContent = data.ch3oh_concentration1 + ' ppm';
}
if (data.ch3oh_concentration2 !== undefined) {
document.getElementById('ch3oh-concentration2').textContent = data.ch3oh_concentration2 + ' ppm';
}
// 电池系统
if (data.ins_soc !== undefined) {
document.getElementById('ins-soc').textContent = (data.ins_soc).toFixed(1) + '%';
}
if (data.dyn_soc !== undefined) {
document.getElementById('dyn-soc').textContent = (data.dyn_soc).toFixed(1) + '%';
}
if (data.ins_voltage_link !== undefined) {
document.getElementById('ins-voltage-link').textContent = (data.ins_voltage_link ).toFixed(2) + ' V';
}
if (data.dyn_voltage_link !== undefined) {
document.getElementById('dyn-voltage-link').textContent = (data.dyn_voltage_link ).toFixed(2) + ' V';
}
if (data.ins_current !== undefined) {
document.getElementById('ins-current').textContent = (data.ins_current).toFixed(2) + ' A';
}
if (data.dyn_current !== undefined) {
document.getElementById('dyn-current').textContent = (data.dyn_current).toFixed(2) + ' A';
}
if (data.ins_total_energy !== undefined) {
document.getElementById('ins-total-energy').textContent = data.ins_total_energy + ' Wh';
}
if (data.dyn_total_energy !== undefined) {
document.getElementById('dyn-total-energy').textContent = data.dyn_total_energy + ' Wh';
}
if (data.ins_power_input !== undefined) {
document.getElementById('ins-power-input').textContent = data.ins_power_input + ' W';
}
if (data.dyn_power_input !== undefined) {
document.getElementById('dyn-power-input').textContent = data.dyn_power_input + ' W';
}
// 继电器状态
if (data.ins_relay_status1 !== undefined) {
document.getElementById('ins-relay-status1').textContent = getRelayStatusText(data.ins_relay_status1);
}
if (data.ins_relay_status2 !== undefined) {
document.getElementById('ins-relay-status2').textContent = getRelayStatusText(data.ins_relay_status2);
}
if (data.dyn_relay_status1 !== undefined) {
document.getElementById('dyn-relay-status1').textContent = getRelayStatusText(data.dyn_relay_status1);
}
if (data.dyn_relay_status2 !== undefined) {
document.getElementById('dyn-relay-status2').textContent = getRelayStatusText(data.dyn_relay_status2);
}
// 报警标志
if (data.dyn_alarm_flag1 !== undefined) {
document.getElementById('dyn-alarm-flag1').textContent = data.dyn_alarm_flag1;
}
if (data.dyn_alarm_flag2 !== undefined) {
document.getElementById('dyn-alarm-flag2').textContent = data.dyn_alarm_flag2;
}
if (data.dyn_alarm_flag3 !== undefined) {
document.getElementById('dyn-alarm-flag3').textContent = data.dyn_alarm_flag3;
}
if (data.dyn_alarm_flag4 !== undefined) {
document.getElementById('dyn-alarm-flag4').textContent = data.dyn_alarm_flag4;
}
if (data.dyn_alarm_flag5 !== undefined) {
document.getElementById('dyn-alarm-flag5').textContent = data.dyn_alarm_flag5;
}
if (data.dyn_alarm_flag6 !== undefined) {
document.getElementById('dyn-alarm-flag6').textContent = data.dyn_alarm_flag6;
}
if (data.ins_alarm_flag1 !== undefined) {
document.getElementById('ins-alarm-flag1').textContent = data.ins_alarm_flag1;
}
if (data.ins_alarm_flag2 !== undefined) {
document.getElementById('ins-alarm-flag2').textContent = data.ins_alarm_flag2;
}
if (data.ins_alarm_flag3 !== undefined) {
document.getElementById('ins-alarm-flag3').textContent = data.ins_alarm_flag3;
}
if (data.ins_alarm_flag4 !== undefined) {
document.getElementById('ins-alarm-flag4').textContent = data.ins_alarm_flag4;
}
if (data.ins_alarm_flag5 !== undefined) {
document.getElementById('ins-alarm-flag5').textContent = data.ins_alarm_flag5;
}
if (data.ins_alarm_flag6 !== undefined) {
document.getElementById('ins-alarm-flag6').textContent = data.ins_alarm_flag6;
}
// 其他系统参数
if (data.device_online_flag1 !== undefined) {
document.getElementById('device-online-flag1').textContent = data.device_online_flag1;
}
if (data.device_online_flag2 !== undefined) {
document.getElementById('device-online-flag2').textContent = data.device_online_flag2;
}
if (data.heartbeat !== undefined) {
document.getElementById('heartbeat').textContent = data.heartbeat;
}
if (data.timestamp !== undefined) {
document.getElementById('timestamp').textContent = new Date(data.timestamp).toLocaleString();
}
}
// FC模式文本转换
function getFCModeText(mode) {
const modes = {
0: '无效',
1: '调试',
2: '自动',
3: '补给'
};
return modes[mode] || '未知模式';
}
// FC状态文本转换
function getFCStatusText(status) {
const statuses = {
0: '无效',
1: '初始化',
2: '待机',
3: '启动中',
4: '运行',
5: '关机中',
6: '故障',
7: '维护',
8: '校准',
9: '测试',
10: '紧急停止',
11: '重启',
12: '升级',
13: '维护完成'
};
return statuses[status] || '未知状态';
}
// 继电器状态文本转换
function getRelayStatusText(status) {
return status === 1 ? '闭合' : '断开';
}
// 折叠面板功能
const coll = document.getElementsByClassName("collapsible");
for (let i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
const content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
// 初始化WebSocket连接
window.addEventListener('load', initWebSocket);
</script>
</body>
</html>
)";
#endif // HTTP_SERVER_INDEX_H