增加了网页服务
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
#include "httpserver.h"
|
||||
#include "index.h"
|
||||
#include "../PowerManger.h"
|
||||
#include "mongoose.h"
|
||||
#include <iostream>
|
||||
#include "json/json.h"
|
||||
|
||||
using json = Json::Value;
|
||||
|
||||
// WebSocket事件处理函数
|
||||
void HttpServer::handleWebSocketEvent(struct mg_connection* c, int ev, void* ev_data, void* fn_data) {
|
||||
HttpServer* server = static_cast<HttpServer*>(fn_data);
|
||||
|
||||
if (ev == MG_EV_OPEN) {
|
||||
// 新连接建立
|
||||
std::lock_guard<std::mutex> lock(server->ws_connections_mutex_);
|
||||
server->ws_connections_.push_back(c);
|
||||
LOG_F(INFO, "WebSocket connection opened: id=%lu fd=%d", c->id, c->fd);
|
||||
} else if (ev == MG_EV_CLOSE || ev == MG_EV_ERROR) {
|
||||
// 连接关闭或错误
|
||||
std::lock_guard<std::mutex> lock(server->ws_connections_mutex_);
|
||||
auto it = std::find(server->ws_connections_.begin(), server->ws_connections_.end(), c);
|
||||
if (it != server->ws_connections_.end()) {
|
||||
LOG_F(ERROR, "WebSocket %s: id=%lu fd=%d",
|
||||
ev == MG_EV_ERROR ? "error" : "closed", c->id, c->fd);
|
||||
server->ws_connections_.erase(it);
|
||||
}
|
||||
} else if (ev == MG_EV_HTTP_MSG) {
|
||||
// HTTP请求处理
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
if (mg_match(hm->uri, mg_str("/ws"), NULL)) {
|
||||
// 升级到WebSocket连接
|
||||
mg_ws_upgrade(c, hm, nullptr);
|
||||
} else {
|
||||
// 返回主页HTML
|
||||
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", INDEX_HTML.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HttpServer::HttpServer(int port) : port_(port), running_(false) {
|
||||
mg_mgr_init(&mgr_);
|
||||
}
|
||||
|
||||
HttpServer::~HttpServer() {
|
||||
stop();
|
||||
mg_mgr_free(&mgr_);
|
||||
}
|
||||
|
||||
bool HttpServer::serverThreadCB(void* pParam) {
|
||||
HttpServer* pThis = static_cast<HttpServer*>(pParam);
|
||||
return pThis->serverThreadFunc();
|
||||
}
|
||||
|
||||
bool HttpServer::serverThreadFunc() {
|
||||
while(running_) {
|
||||
mg_mgr_poll(&mgr_, 1000);
|
||||
|
||||
// 定期推送系统数据
|
||||
static uint64_t last_push_time = 0;
|
||||
uint64_t now = mg_millis();
|
||||
if (now - last_push_time > 1000) { // 每秒推送一次
|
||||
last_push_time = now;
|
||||
pushSystemData();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HttpServer::pushSystemData() {
|
||||
if (!m_systemData) return;
|
||||
// 序列化系统数据为JSON
|
||||
json j;
|
||||
//燃料电池系统参数
|
||||
j["fc_mode"] = Json::Value(m_systemData->fc_mode); // 燃料电池系统运行模式:00H-无效, 01H-调试, 02H-自动, 03H-补给
|
||||
j["fc_status"] = Json::Value(m_systemData->fc_status); // 燃料电池状态:00H-无效, 01H-初始化, ..., 0DH-维护完成
|
||||
j["fc_fault_level"] = Json::Value(m_systemData->fc_fault_level);
|
||||
|
||||
//功率和时间参数
|
||||
j["output_power_limit"] = Json::Value(m_systemData->output_power_limit); // 系统输出功率限制值,单位:W
|
||||
j["total_generation_time"] = Json::Value(m_systemData->total_generation_time); // 系统累计发电时间,单位:0.1小时
|
||||
j["total_generation_power"] = Json::Value(m_systemData->total_generation_power); // 系统累计发电功率,单位:W
|
||||
|
||||
//燃料电池故障信息
|
||||
j["fc_fault_level_1"] = Json::Value(m_systemData->fc_fault_level_1);
|
||||
j["fc_fault_level_2"] = Json::Value(m_systemData->fc_fault_level_2);
|
||||
j["fc_fault_level_3"] = Json::Value(m_systemData->fc_fault_level_3);
|
||||
j["fc_fault_level_4"] = Json::Value(m_systemData->fc_fault_level_4);
|
||||
|
||||
//燃料容量
|
||||
j["hydrogen_capacity"] = Json::Value(m_systemData->hydrogen_capacity); // 储氢罐剩余容量百分比,单位:%
|
||||
j["liquid_oxygen_capacity"] = Json::Value(m_systemData->liquid_oxygen_capacity); // 液氧罐剩余容量百分比,单位:%
|
||||
|
||||
//温度压力参数
|
||||
j["palladium_temp"] = Json::Value(m_systemData->palladium_temp); // 钯膜最高温度,单位:℃
|
||||
j["main_pipe_pressure"] = Json::Value(m_systemData->main_pipe_pressure); // 主水路压力,单位:0.01kPa
|
||||
j["aux_pipe_pressure"] = Json::Value(m_systemData->aux_pipe_pressure); // 辅水路压力,单位:0.01kPa
|
||||
|
||||
//舱室环境参数
|
||||
j["cabin_pressure1"] = Json::Value(m_systemData->cabin_pressure1); // 舱室1压力,单位:0.01kPa
|
||||
j["cabin_pressure2"] = Json::Value(m_systemData->cabin_pressure2); // 舱室2压力,单位:0.01kPa
|
||||
j["cabin_temp1"] = Json::Value(m_systemData->cabin_temp1); // 舱室1温度,单位:0.01℃
|
||||
j["cabin_temp2"] = Json::Value(m_systemData->cabin_temp2); // 舱室2温度,单位:0.01℃
|
||||
j["cabin_humidity1"] = Json::Value(m_systemData->cabin_humidity1); // 舱室1湿度,单位:0.01%RH
|
||||
j["cabin_humidity2"] = Json::Value(m_systemData->cabin_humidity2); // 舱室2湿度,单位:0.01%RH
|
||||
|
||||
//火焰探测器
|
||||
j["flame_detector1"] = Json::Value(m_systemData->flame_detector1); // 火焰探测器1状态:00H-无效, 01H-报警, 02H-故障
|
||||
j["flame_detector2"] = Json::Value(m_systemData->flame_detector2); // 火焰探测器2状态:00H-无效, 01H-报警, 02H-故障
|
||||
|
||||
//气体浓度
|
||||
j["h2_concentration1"] = Json::Value(m_systemData->h2_concentration1); // 舱室H2浓度1,单位:0.01% LEL
|
||||
j["h2_concentration2"] = Json::Value(m_systemData->h2_concentration2); // 舱室H2浓度2,单位:0.01% LEL
|
||||
j["h2_concentration3"] = Json::Value(m_systemData->h2_concentration3); // 舱室H2浓度3,单位:0.01% LEL
|
||||
j["o2_concentration1"] = Json::Value(m_systemData->o2_concentration1); // 舱室O2浓度1,单位:0.01% LEL
|
||||
j["o2_concentration2"] = Json::Value(m_systemData->o2_concentration2); // 舱室O2浓度2,单位:0.01% LEL
|
||||
j["ch3oh_concentration1"] = Json::Value(m_systemData->ch3oh_concentration1); // 舱室甲醇气体浓度1,单位:0.01% LEL
|
||||
j["ch3oh_concentration2"] = Json::Value(m_systemData->ch3oh_concentration2); // 舱室甲醇气体浓度2,单位:0.01% LEL
|
||||
|
||||
//保留字段
|
||||
j["cabin_ox_concentration"] = Json::Value(m_systemData->cabin_ox_concentration); // 仪表舱内氧气浓度,单位:0.1%
|
||||
j["cabin_temperature"] = Json::Value(m_systemData->cabin_temperature); // 仪表舱内温度,单位:0.1℃
|
||||
j["cabin_humidity"] = Json::Value(m_systemData->cabin_humidity); // 仪表舱内湿度,单位:0.1%RH
|
||||
j["cabin_pressure"] = Json::Value(m_systemData->cabin_pressure); // 仪表舱内大气压,单位:0.2kPa
|
||||
|
||||
//动力舱参数
|
||||
j["power_cabin_ox_concentration"] = Json::Value(m_systemData->power_cabin_ox_concentration); // 动力舱内氧气浓度,单位:0.1%
|
||||
j["power_cabin_temperature"] = Json::Value(m_systemData->power_cabin_temperature); // 动力舱内温度,单位:0.1℃
|
||||
j["power_cabin_humidity"] = Json::Value(m_systemData->power_cabin_humidity); // 动力舱内湿度,单位:0.1%RH
|
||||
j["power_cabin_pressure"] = Json::Value(m_systemData->power_cabin_pressure); // 动力舱内大气压,单位:0.2kPa
|
||||
|
||||
//电池报警标志
|
||||
// uint8_t dyn_alarm_flag[6]; // 动力锂电池报警标志
|
||||
// uint8_t ins_alarm_flag[6]; // 仪表锂电池报警标志
|
||||
j["dyn_alarm_flag1"] = Json::Value(m_systemData->dyn_alarm_flag[0]);
|
||||
j["dyn_alarm_flag2"] = Json::Value(m_systemData->dyn_alarm_flag[1]);
|
||||
j["dyn_alarm_flag3"] = Json::Value(m_systemData->dyn_alarm_flag[2]);
|
||||
j["dyn_alarm_flag4"] = Json::Value(m_systemData->dyn_alarm_flag[3]);
|
||||
j["dyn_alarm_flag5"] = Json::Value(m_systemData->dyn_alarm_flag[4]);
|
||||
j["dyn_alarm_flag6"] = Json::Value(m_systemData->dyn_alarm_flag[5]);
|
||||
|
||||
j["ins_alarm_flag1"] = Json::Value(m_systemData->ins_alarm_flag[0]);
|
||||
j["ins_alarm_flag2"] = Json::Value(m_systemData->ins_alarm_flag[1]);
|
||||
j["ins_alarm_flag3"] = Json::Value(m_systemData->ins_alarm_flag[2]);
|
||||
j["ins_alarm_flag4"] = Json::Value(m_systemData->ins_alarm_flag[3]);
|
||||
j["ins_alarm_flag5"] = Json::Value(m_systemData->ins_alarm_flag[4]);
|
||||
j["ins_alarm_flag6"] = Json::Value(m_systemData->ins_alarm_flag[5]);
|
||||
|
||||
//继电器状态
|
||||
j["ins_relay_status1"] = Json::Value(m_systemData->ins_relay_status1); // 仪表电池继电器状态
|
||||
j["ins_relay_status2"] = Json::Value(m_systemData->ins_relay_status2); // 仪表电池预充继电器和负极继电器状态
|
||||
j["dyn_relay_status1"] = Json::Value(m_systemData->dyn_relay_status1); // 动力电池正极与充电继电器状态
|
||||
j["dyn_relay_status2"] = Json::Value(m_systemData->dyn_relay_status2); // 动力电池预充与负极继电器状态
|
||||
|
||||
//电池功率参数
|
||||
j["ins_max_discharge_power"] = Json::Value(m_systemData->ins_max_discharge_power); // 仪表电池最大允许放电功率,单位:0.05kW
|
||||
j["dyn_max_discharge_power"] = Json::Value(m_systemData->dyn_max_discharge_power); // 动力电池最大允许放电功率,单位:0.05kW
|
||||
|
||||
//电池SOC
|
||||
j["ins_soc"] = Json::Value(m_systemData->ins_soc); // 仪表电池SOC,单位:0.1%
|
||||
j["dyn_soc"] = Json::Value(m_systemData->dyn_soc); // 动力电池SOC,单位:0.1%
|
||||
|
||||
//电池能量
|
||||
j["ins_total_energy"] = Json::Value(m_systemData->ins_total_energy); // 仪表电池能量,单位:0.01kWh
|
||||
j["dyn_total_energy"] = Json::Value(m_systemData->dyn_total_energy); // 动力电池能量,单位:0.01kWh
|
||||
|
||||
//电池输入功率
|
||||
j["ins_power_input"] = Json::Value(m_systemData->ins_power_input);
|
||||
j["dyn_power_input"] = Json::Value(m_systemData->dyn_power_input);
|
||||
|
||||
//电池电压电流
|
||||
j["ins_voltage_link"] = Json::Value(m_systemData->ins_voltage_link); // 仪表电池LINK端电压,单位:0.01V
|
||||
j["ins_voltage_pack"] = Json::Value(m_systemData->ins_voltage_pack); // 仪表电池PACK端电压,单位:0.01V
|
||||
j["ins_current"] = Json::Value(m_systemData->ins_current); // 仪表电池电流,单位:0.01A
|
||||
j["ins_resistance_pos"] = Json::Value(m_systemData->ins_resistance_pos); // 仪表电池正极绝缘电阻,单位:kΩ
|
||||
j["ins_resistance_neg"] = Json::Value(m_systemData->ins_resistance_neg); // 仪表电池负极绝缘电阻,单位:kΩ
|
||||
j["dyn_voltage_link"] = Json::Value(m_systemData->dyn_voltage_link); // 动力电池LINK端电压,单位:0.01V
|
||||
j["dyn_voltage_pack"] = Json::Value(m_systemData->dyn_voltage_pack); // 动力电池PACK端电压,单位:0.01V
|
||||
j["dyn_current"] = Json::Value(m_systemData->dyn_current); // 动力电池电流,单位:0.05A
|
||||
j["dyn_resistance_pos"] = Json::Value(m_systemData->dyn_resistance_pos); // 动力电池正极绝缘电阻,单位:kΩ
|
||||
j["dyn_resistance_neg"] = Json::Value(m_systemData->dyn_resistance_neg); // 动力电池负极绝缘电阻,单位:kΩ
|
||||
|
||||
|
||||
//紧急状态
|
||||
j["ins_emergency_status"] = Json::Value(m_systemData->ins_emergency_status); // 紧急状态:00H-无紧急, 01H-紧急
|
||||
j["dyn_emergency_status"] = Json::Value(m_systemData->dyn_emergency_status); // 紧急状态:00H-无紧急, 01H-紧急
|
||||
|
||||
j["ins_soc_threshold1"] = Json::Value(m_systemData->ins_soc_threshold1); // 仪表电池1 SOC门限
|
||||
j["ins_soc_threshold2"] = Json::Value(m_systemData->ins_soc_threshold2); // 仪表电池2 SOC门限
|
||||
j["ins_soc_threshold3"] = Json::Value(m_systemData->ins_soc_threshold3); // 仪表电池3 SOC门限
|
||||
j["dyn_soc_threshold1"] = Json::Value(m_systemData->dyn_soc_threshold1); // 动力电池1 SOC门限
|
||||
j["dyn_soc_threshold2"] = Json::Value(m_systemData->dyn_soc_threshold2); // 动力电池2 SOC门限
|
||||
j["dyn_soc_threshold3"] = Json::Value(m_systemData->dyn_soc_threshold3); // 动力电池3 SOC门限
|
||||
j["ins_power_limit1"] = Json::Value(m_systemData->ins_power_limit1); // 仪表电池1功率限制值
|
||||
j["ins_power_limit2"] = Json::Value(m_systemData->ins_power_limit2); // 仪表电池2功率限制值
|
||||
j["dyn_power_limit1"] = Json::Value(m_systemData->dyn_power_limit1); // 动力电池1功率限制值
|
||||
j["dyn_power_limit2"] = Json::Value(m_systemData->dyn_power_limit2); // 动力电池2功率限制值
|
||||
|
||||
//设备在线状态
|
||||
j["device_online_flag1"] = Json::Value(m_systemData->device_online_flag1);
|
||||
j["device_online_flag2"] = Json::Value(m_systemData->device_online_flag2);
|
||||
|
||||
//复合管控器心跳计算器
|
||||
j["heartbeat"] = Json::Value(m_systemData->heartbeat);
|
||||
|
||||
// 时间戳
|
||||
j["timestamp"] = Json::Value((Json::UInt64)mg_millis());
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
std::string msg = Json::writeString(builder, j);
|
||||
|
||||
// 发送给所有WebSocket客户端
|
||||
std::lock_guard<std::mutex> lock(ws_connections_mutex_);
|
||||
for (auto c : ws_connections_) {
|
||||
mg_ws_send(c, msg.c_str(), msg.size(), WEBSOCKET_OP_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void HttpServer::start() {
|
||||
if (running_) return;
|
||||
|
||||
std::string addr = "http://0.0.0.0:" + std::to_string(port_);
|
||||
mg_http_listen(&mgr_, addr.c_str(), [](mg_connection *c, int ev, void *ev_data) {
|
||||
HttpServer* server = static_cast<HttpServer*>(c->fn_data);
|
||||
if (server) {
|
||||
server->handleWebSocketEvent(c, ev, ev_data, c->fn_data);
|
||||
}
|
||||
}, this);
|
||||
|
||||
running_ = true;
|
||||
m_ServerThread.Initialise(serverThreadCB, this);
|
||||
m_ServerThread.Start();
|
||||
|
||||
std::cout << "HTTP server started on " << addr << std::endl;
|
||||
LOG_F(INFO, "HTTP server started on %s", addr.c_str());
|
||||
}
|
||||
|
||||
void HttpServer::stop() {
|
||||
if (!running_) return;
|
||||
|
||||
running_ = false;
|
||||
m_ServerThread.Stop();
|
||||
|
||||
// 关闭所有WebSocket连接
|
||||
std::lock_guard<std::mutex> lock(ws_connections_mutex_);
|
||||
for (auto c : ws_connections_) {
|
||||
mg_ws_send(c, "", 0, WEBSOCKET_OP_CLOSE);
|
||||
}
|
||||
ws_connections_.clear();
|
||||
|
||||
std::cout << "HTTP server stopped" << std::endl;
|
||||
}
|
||||
|
||||
bool HttpServer::isRunning() const {
|
||||
return running_;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user