- 修复WebSocket推送无背压导致mongoose发送缓冲无限增长的内存泄露 - 为SystemData增加互斥锁,消除pushSystemData与主线程的数据竞争 - 修复网页状态文本判断反转、漏水告警阈值、FC状态、H2单位等显示bug - 按协议修正电池紧急状态枚举解码(0x3A-0x3D为1-4级报警) - 调整CMake适配系统安装的MOOS/IvP及jsoncpp,删除ARM专用build_debug.sh
1072 lines
70 KiB
C++
1072 lines
70 KiB
C++
#include "httpserver.h"
|
|
#include "index.h"
|
|
#include "dashboard.h"
|
|
#include "../PowerManger.h"
|
|
#include "mongoose.h"
|
|
#include <iostream>
|
|
#include "json/json.h"
|
|
#include <sys/resource.h>
|
|
#include "data.h"
|
|
#include "logpage.h"
|
|
#include "testpage.h"
|
|
#include "degubpage.h"
|
|
#include "batteryoperation.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_WS_OPEN) {
|
|
// WebSocket连接成功建立
|
|
std::lock_guard<std::mutex> lock(server->ws_connections_mutex_);
|
|
server->ws_connections_.push_back(c);
|
|
LOG_F(INFO, "WebSocket connection established: 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()) {
|
|
if (ev == MG_EV_ERROR) {
|
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
if (errno != 0) {
|
|
LOG_F(ERROR, "WebSocket error: id=%lu fd=%d, errno=%d",
|
|
c->id, c->fd, errno);
|
|
// 打印socket错误信息
|
|
char buf[256];
|
|
strerror_r(errno, buf, sizeof(buf));
|
|
LOG_F(ERROR, "Socket error: %s", buf);
|
|
} else {
|
|
LOG_F(ERROR, "WebSocket connection closed abnormally: id=%lu fd=%d",
|
|
c->id, c->fd);
|
|
}
|
|
} else {
|
|
LOG_F(INFO, "WebSocket closed: id=%lu fd=%d", c->id, c->fd);
|
|
}
|
|
server->ws_connections_.erase(it);
|
|
|
|
// 检查系统资源限制
|
|
static int fd_limit_checked = 0;
|
|
if (!fd_limit_checked) {
|
|
fd_limit_checked = 1;
|
|
struct rlimit lim;
|
|
if (getrlimit(RLIMIT_NOFILE, &lim) == 0) {
|
|
LOG_F(INFO, "File descriptor limits: soft=%lu hard=%lu",
|
|
lim.rlim_cur, lim.rlim_max);
|
|
}
|
|
}
|
|
}
|
|
} else if (ev == MG_EV_WS_MSG) {
|
|
// WebSocket消息处理
|
|
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
|
|
std::string msg(wm->data.buf, wm->data.len);
|
|
handleLogRequest(c, msg);
|
|
} 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连接
|
|
LOG_F(INFO, "Upgrading to WebSocket: id=%lu fd=%d", c->id, c->fd);
|
|
mg_ws_upgrade(c, hm, nullptr);
|
|
LOG_F(INFO, "WebSocket upgrade completed: id=%lu fd=%d", c->id, c->fd);
|
|
} else if (mg_match(hm->uri, mg_str("/dashboard"), NULL)) {
|
|
// 返回仪表盘HTML
|
|
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", DASHBOARD_HTML.c_str());
|
|
} else if (mg_match(hm->uri, mg_str("/data"), NULL)) {
|
|
// 返回数据页面HTML
|
|
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", DATA_HTML.c_str());
|
|
} else if (mg_match(hm->uri, mg_str("/logs"), NULL)) {
|
|
// 返回日志页面HTML
|
|
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", LOG_PAGE_HTML.c_str());
|
|
} else if (mg_match(hm->uri, mg_str("/testpage"), NULL)) {
|
|
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
|
|
// 解析POST请求并调用处理函数
|
|
std::string msg(hm->body.buf, hm->body.len);
|
|
handleTestPage(c, msg);
|
|
} else {
|
|
// 返回测试页面HTML
|
|
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", TESTPAGE_HTML.c_str());
|
|
}
|
|
} else if (mg_match(hm->uri, mg_str("/debug"), NULL)) {
|
|
// 返回调试页面HTML
|
|
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", DEBUGPAGE_HTML.c_str());
|
|
} else if (mg_match(hm->uri, mg_str("/battery"), NULL)) {
|
|
// 返回电池操作页面HTML
|
|
mg_http_reply(c, 200, "Content-Type: text/html; charset=utf-8\r\n", BATTERY_OPERATION_HTML.c_str());
|
|
} else if (mg_match(hm->uri, mg_str("/battery/control"), NULL)) {
|
|
// 处理电池控制POST请求
|
|
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
|
|
// 解析表单数据
|
|
struct mg_str body = hm->body;
|
|
unsigned char fuelCellMode = 0;
|
|
unsigned char fuelCellCommand = 0;
|
|
unsigned short fuelCellPower = 0;
|
|
unsigned char instrumentBattery = 0;
|
|
unsigned char powerBattery = 0;
|
|
unsigned short powerBatteryPower = 0;
|
|
unsigned char hostStatus = 0;
|
|
|
|
char tmp[16] = {0};
|
|
mg_http_get_var(&body, "fuelCellMode", tmp, sizeof(tmp));
|
|
fuelCellMode = (unsigned char)strtoul(tmp, NULL, 16);
|
|
mg_http_get_var(&body, "fuelCellCommand", tmp, sizeof(tmp));
|
|
fuelCellCommand = (unsigned char)strtoul(tmp, NULL, 16);
|
|
mg_http_get_var(&body, "fuelCellPower", tmp, sizeof(tmp));
|
|
fuelCellPower = (unsigned short)atoi(tmp);
|
|
mg_http_get_var(&body, "instrumentBattery", tmp, sizeof(tmp));
|
|
instrumentBattery = (unsigned char)strtoul(tmp, NULL, 16);
|
|
mg_http_get_var(&body, "instrumentBatteryCharge", tmp, sizeof(tmp));
|
|
unsigned char instrumentBatteryCharge = (unsigned char)atoi(tmp);
|
|
mg_http_get_var(&body, "powerBattery", tmp, sizeof(tmp));
|
|
powerBattery = (unsigned char)strtoul(tmp, NULL, 16);
|
|
mg_http_get_var(&body, "powerBatteryPower", tmp, sizeof(tmp));
|
|
powerBatteryPower = (unsigned short)atoi(tmp);
|
|
mg_http_get_var(&body, "hostStatus", tmp, sizeof(tmp));
|
|
hostStatus = (unsigned char)strtoul(tmp, NULL, 16);
|
|
|
|
// 记录接收到的配置
|
|
LOG_F(INFO, "Received battery control config: "
|
|
"fuelCellMode=%02XH, fuelCellCommand=%02XH, fuelCellPower=%d, "
|
|
"instrumentBattery=%02XH, instrumentBatteryCharge=%d, powerBattery=%02XH, powerBatteryPower=%d, "
|
|
"hostStatus=%02XH",
|
|
fuelCellMode, fuelCellCommand, fuelCellPower,
|
|
instrumentBattery, instrumentBatteryCharge, powerBattery, powerBatteryPower, hostStatus);
|
|
|
|
m_powerManger->m_CcuColCmd.fcmode = fuelCellMode;
|
|
m_powerManger->m_CcuColCmd.fcuCmd = fuelCellCommand;
|
|
m_powerManger->m_CcuColCmd.fcuPowerEfficiency = fuelCellPower;
|
|
m_powerManger->m_CcuColCmd.insBatCmd = instrumentBattery;
|
|
cout << "powerBatteryPower:" << (int)instrumentBattery << endl;
|
|
m_powerManger->m_CcuColCmd.powerBatCmd = powerBattery;
|
|
m_powerManger->m_CcuColCmd.powerBatEfficiency = powerBatteryPower;
|
|
m_powerManger->m_CcuColCmd.masterState = hostStatus;
|
|
m_powerManger->m_CcuColCmd.insChargeEnable = instrumentBatteryCharge;
|
|
cout << "m_powerManger->m_CcuColCmd.masterState:" << (int)m_powerManger->m_CcuColCmd.masterState << endl;
|
|
|
|
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
|
|
"{\"success\": true, \"message\": \"电池配置提交成功\"}");
|
|
} else {
|
|
mg_http_reply(c, 405, "Content-Type: text/plain\r\n", "Method Not Allowed");
|
|
}
|
|
} else if (mg_match(hm->uri, mg_str("/ws/debug"), NULL)) {
|
|
// 升级到调试WebSocket连接
|
|
LOG_F(INFO, "Upgrading to Debug WebSocket: id=%lu fd=%d", c->id, c->fd);
|
|
mg_ws_upgrade(c, hm, nullptr);
|
|
LOG_F(INFO, "Debug WebSocket upgrade completed: id=%lu fd=%d", c->id, c->fd);
|
|
} else if (mg_match(hm->uri, mg_str("/moosdb_test"), NULL)) {
|
|
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
|
|
// 解析JSON请求
|
|
char *key = mg_json_get_str(hm->body, "$.key");
|
|
char *value = mg_json_get_str(hm->body, "$.value");
|
|
|
|
if (key && value) {
|
|
LOG_F(INFO, "Received MOOSDB test message: key=%s, value=%s", key, value);
|
|
|
|
// TODO: 这里添加处理MOOSDB测试消息的逻辑
|
|
// 例如: m_powerManger->handleMoosdbTest(key, value);
|
|
bool success = true;
|
|
success = m_powerManger->sendNotification(key,value);
|
|
if (!success) {
|
|
mg_http_reply(c, 500, "Content-Type: application/json\r\n",
|
|
"{\"success\": false, \"error\": \"Failed to send MOOSDB test message\"}");
|
|
return;
|
|
}
|
|
// 返回成功响应
|
|
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
|
|
"{\"success\": true, \"message\": \"MOOSDB test message received\"}");
|
|
} else {
|
|
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
|
|
"{\"success\": false, \"error\": \"key and value fields are required\"}");
|
|
}
|
|
|
|
// 释放分配的内存
|
|
if (key) free(key);
|
|
if (value) free(value);
|
|
} else {
|
|
mg_http_reply(c, 405, "Content-Type: text/plain\r\n", "Method Not Allowed");
|
|
}
|
|
} else if (mg_match(hm->uri, mg_str("/control"), NULL)) {
|
|
// 处理断路器控制请求
|
|
if (mg_strcmp(hm->method, mg_str("POST")) == 0) {
|
|
// 解析JSON请求
|
|
char *device_type = mg_json_get_str(hm->body, "$.device_type");
|
|
char *device_id = mg_json_get_str(hm->body, "$.device_id");
|
|
char *action = mg_json_get_str(hm->body, "$.action");
|
|
|
|
bool success = true;
|
|
std::string device_type_str = device_type? std::string(device_type) : "";
|
|
std::string device_id_str = device_id ? std::string(device_id) : "";
|
|
std::string action_str = action ? std::string(action) : "";
|
|
if (device_type && device_id && action) {
|
|
//TODO: 处理断路器控制逻辑
|
|
LOG_F(INFO, "Received control request: device_type=%s, device_id=%s, action=%s ,from Net DashBoard id=%lu fd=%d",
|
|
device_type, device_id, action, c->id, c->fd);
|
|
char opt = (action_str == "open") ? 0 : 1;
|
|
if(device_type_str == "meter_bus")
|
|
{
|
|
if (device_id_str == "battery_meter")
|
|
{
|
|
success = m_lowerCommManager->operate_LV_lithiumBatteryGroupInstrumentCircuit_Breaker(opt);
|
|
} else if (device_id_str == "bow_low_dist")
|
|
{
|
|
success = m_lowerCommManager->operate_LV_bowLowVoltageDistributionBoxCircuit_Breaker(opt);
|
|
} else if (device_id_str == "unit4_dc48v"){
|
|
success = m_lowerCommManager->operate_LV_unit4Dc48V_Breaker(opt);
|
|
} else if (device_id_str == "dc_c1"){
|
|
success = m_lowerCommManager->operate_LV_dcC1Panel_Breaker(opt);
|
|
} else if(device_id_str == "reserve1"){
|
|
success = m_lowerCommManager->operate_LV_reservedCircuit1_Breaker(opt);
|
|
} else if(device_id_str == "reserve2"){
|
|
success = m_lowerCommManager->operate_LV_reservedCircuit2_Breaker(opt);
|
|
} else if(device_id_str == "emergency_battery2"){
|
|
success = m_lowerCommManager->operate_LV_mergencyLithiumBatteryGroup2Circuit_Breaker(opt);
|
|
}
|
|
}
|
|
else if (device_type_str == "bow_high_vol")
|
|
{
|
|
if (device_id_str == "bow_ft1_3") {
|
|
success = m_lowerCommManager->operate_HVA_bowFTDevice123Circuit_Breaker(opt);
|
|
} else if (device_id_str == "opening_mechanism") {
|
|
success = m_lowerCommManager->operate_HVA_actuatorCircuit_Breaker(opt);
|
|
} else if (device_id_str == "mast_steering") {
|
|
success = m_lowerCommManager->operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(opt);
|
|
} else if (device_id_str == "xcz") {
|
|
success = m_lowerCommManager->operate_HVA_xczCircuit_Breaker(opt);
|
|
} else if (device_id_str == "bow_rudder") {
|
|
success = m_lowerCommManager->operate_HVA_bowRudderControlBoxCircuit_Breaker(opt);
|
|
} else if (device_id_str == "water_cover") {
|
|
success = m_lowerCommManager->operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(opt);
|
|
}
|
|
} else if (device_type_str == "high_vol_bus")
|
|
{
|
|
if (device_id_str == "fuel_cell") {
|
|
success = m_lowerCommManager->operate_HV_fuelCellCircuit_Breaker(opt);
|
|
} else if (device_id_str == "power_battery") {
|
|
success = m_lowerCommManager->operate_HV_powerLithiumBattery_Breaker(opt);
|
|
} else if (device_id_str == "propulsion_motor") {
|
|
success = m_lowerCommManager->operate_HV_propulsionMotor_Breaker(opt);
|
|
} else if (device_id_str == "battery_meter") {
|
|
success = m_lowerCommManager->operate_HV_lithiumBatteryMeter_Breaker(opt);
|
|
} else if (device_id_str == "dcdc5") {
|
|
success = m_lowerCommManager->operate_HV_dcDc5Module_Breaker(opt);
|
|
} else if (device_id_str == "bow_distribution") {
|
|
success = m_lowerCommManager->operate_HV_bowHighVoltageBox_Breaker(opt);
|
|
} else if (device_id_str == "stern_ft45") {
|
|
success = m_lowerCommManager->operate_HV_sternFt45_Breaker(opt);
|
|
} else if (device_id_str == "stern_rudder1") {
|
|
success = m_lowerCommManager->operate_HV_sternRudder1_Breaker(opt);
|
|
} else if (device_id_str == "stern_rudder2") {
|
|
success = m_lowerCommManager->operate_HV_sternRudder2_Breaker(opt);
|
|
} else if (device_id_str == "fb_reserve") {
|
|
success = m_lowerCommManager->operate_HV_fbReserved_Breaker(opt);
|
|
} else if (device_id_str == "tyz_reserve") {
|
|
success = m_lowerCommManager->operate_HV_tyzReserved_Breaker(opt);
|
|
} else if (device_id_str == "reserve") {
|
|
success = m_lowerCommManager->operate_HV_reserved_Breaker(opt);
|
|
} else if (device_id_str == "dcdc5_start") {
|
|
success = m_lowerCommManager->operate_HV_dcDc5_Breaker(opt);
|
|
} else if (device_id_str == "cooling_system") {
|
|
success = m_lowerCommManager->operate_HV_coolingSystem_Breaker(opt);
|
|
}
|
|
} else if (device_type_str == "bow_low_vol")
|
|
{
|
|
if (device_id_str == "unit1") {
|
|
success = m_lowerCommManager->operate_LVA_unit1Circuit_Breaker(opt);
|
|
} else if (device_id_str == "unit2") {
|
|
success = m_lowerCommManager->operate_LVA_unit2Circuit_Breaker(opt);
|
|
} else if (device_id_str == "unit3") {
|
|
success = m_lowerCommManager->operate_LVA_unit3Circuit_Breaker(opt);
|
|
} else if (device_id_str == "unit5") {
|
|
success = m_lowerCommManager->operate_LVA_unit5Circuit_Breaker(opt);
|
|
} else if (device_id_str == "bow_pz") {
|
|
success = m_lowerCommManager->operate_LVA_bowPZDeviceCircuit_Breaker(opt);
|
|
} else if (device_id_str == "reserve1") {
|
|
success = m_lowerCommManager->operate_LVA_reservedCircuit1_Breaker(opt);
|
|
} else if (device_id_str == "reserve2") {
|
|
success = m_lowerCommManager->operate_LVA_reservedCircuit2_Breaker(opt);
|
|
} else if (device_id_str == "emergency_battery1") {
|
|
success = m_lowerCommManager->operate_LVA_mergencyLithiumBatteryGroup1Circuit_Breaker(opt);
|
|
}
|
|
}
|
|
const char *message = success ? "操作成功" : "操作失败";
|
|
// 返回JSON响应
|
|
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
|
|
"{\"success\": %s, \"message\": \"%s\"}",
|
|
success ? "true" : "false", message);
|
|
} else {
|
|
mg_http_reply(c, 400, "Content-Type: text/plain\r\n", "Invalid request");
|
|
}
|
|
// 释放分配的内存
|
|
if (device_type) free(device_type);
|
|
if (device_id) free(device_id);
|
|
if (action) free(action);
|
|
} else {
|
|
mg_http_reply(c, 405, "Content-Type: text/plain\r\n", "Method Not Allowed");
|
|
}
|
|
} 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;
|
|
static uint64_t last_log_check_time = 0;
|
|
uint64_t now = mg_millis();
|
|
|
|
if (now - last_push_time > 1000) { // 每秒推送一次
|
|
last_push_time = now;
|
|
pushSystemData();
|
|
}
|
|
|
|
if (now - last_log_check_time > 500) { // 每500ms检查一次日志
|
|
last_log_check_time = now;
|
|
monitorLogFile();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void HttpServer::pushSystemData() {
|
|
if (!m_systemData) {
|
|
LOG_F(ERROR, "System data pointer is null");
|
|
return;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> dataLock(m_systemData->m_dataMutex);
|
|
|
|
// 序列化系统数据为JSON
|
|
json j;
|
|
|
|
// 初始化所有字段为默认值
|
|
j["fc_mode"] = m_systemData->fc_mode ? Json::Value(m_systemData->fc_mode) : Json::Value(0);
|
|
j["fc_status"] = m_systemData->fc_status ? Json::Value(m_systemData->fc_status) : Json::Value(0);
|
|
j["fc_fault_level"] = m_systemData->fc_fault_level ? Json::Value(m_systemData->fc_fault_level) : Json::Value(0);
|
|
|
|
//功率和时间参数
|
|
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压力,单位:kPa
|
|
j["cabin_pressure2"] = Json::Value(m_systemData->cabin_pressure2); // 舱室2压力,单位:kPa
|
|
j["cabin_temp1"] = Json::Value(m_systemData->cabin_temp1); // 舱室1温度,单位:℃
|
|
j["cabin_temp2"] = Json::Value(m_systemData->cabin_temp2); // 舱室2温度,单位:℃
|
|
j["cabin_humidity1"] = Json::Value(m_systemData->cabin_humidity1); // 舱室1湿度,单位:%RH
|
|
j["cabin_humidity2"] = Json::Value(m_systemData->cabin_humidity2); // 舱室2湿度,单位:%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,单位:% LEL
|
|
j["h2_concentration2"] = Json::Value(m_systemData->h2_concentration2); // 舱室H2浓度2,单位:% LEL
|
|
j["h2_concentration3"] = Json::Value(m_systemData->h2_concentration3); // 舱室H2浓度3,单位:% LEL
|
|
j["o2_concentration1"] = Json::Value(m_systemData->o2_concentration1); // 舱室O2浓度1,单位:% LEL
|
|
j["o2_concentration2"] = Json::Value(m_systemData->o2_concentration2); // 舱室O2浓度2,单位:% LEL
|
|
j["ch3oh_concentration1"] = Json::Value(m_systemData->ch3oh_concentration1); // 舱室甲醇气体浓度1,单位:% LEL
|
|
j["ch3oh_concentration2"] = Json::Value(m_systemData->ch3oh_concentration2); // 舱室甲醇气体浓度2,单位:% LEL
|
|
|
|
//保留字段
|
|
j["cabin_ox_concentration"] = Json::Value(m_systemData->cabin_ox_concentration); // 仪表舱内氧气浓度,单位:%
|
|
j["cabin_temperature"] = Json::Value(m_systemData->cabin_temperature); // 仪表舱内温度,单位:℃
|
|
j["cabin_humidity"] = Json::Value(m_systemData->cabin_humidity); // 仪表舱内湿度,单位:%RH
|
|
j["cabin_pressure"] = Json::Value(m_systemData->cabin_pressure); // 仪表舱内大气压,单位:kPa
|
|
|
|
//动力舱参数
|
|
j["power_cabin_ox_concentration"] = Json::Value(m_systemData->power_cabin_ox_concentration); // 动力舱内氧气浓度,单位:%
|
|
j["power_cabin_temperature"] = Json::Value(m_systemData->power_cabin_temperature); // 动力舱内温度,单位:℃
|
|
j["power_cabin_humidity"] = Json::Value(m_systemData->power_cabin_humidity); // 动力舱内湿度,单位:%RH
|
|
j["power_cabin_pressure"] = Json::Value(m_systemData->power_cabin_pressure); // 动力舱内大气压,单位:kPa
|
|
|
|
//电池报警标志
|
|
// 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_pos_relay_status"] = Json::Value(m_systemData->ins_pos_relay_status); // 仪表电池正极继电器状态 1:接通 2:断开 其他:无效
|
|
j["ins_charge_relay_status"] = Json::Value(m_systemData->ins_charge_relay_status); // 仪表电池充电继电器状态 1:接通 2:断开 其他:无效
|
|
j["ins_precharge_relay_status"] = Json::Value(m_systemData->ins_precharge_relay_status); // 仪表电池预充继电器状态 1:接通 2:断开 其他:无效
|
|
j["ins_neg_relay_status"] = Json::Value(m_systemData->ins_neg_relay_status); // 仪表电池负极继电器状态 1:接通 2:断开 其他:无效
|
|
|
|
j["dyn_pos_relay_status"] = Json::Value(m_systemData->dyn_pos_relay_status); // 动力电池正极继电器状态 1:接通 2:断开 其他:无效
|
|
j["dyn_charge_relay_status"] = Json::Value(m_systemData->dyn_charge_relay_status); // 动力电池充电继电器状态 1:接通 2:断开 其他:无效
|
|
j["dyn_precharge_relay_status"] = Json::Value(m_systemData->dyn_precharge_relay_status); // 动力电池预充继电器状态 1:接通 2:断开 其他:无效
|
|
j["dyn_neg_relay_status"] = Json::Value(m_systemData->dyn_neg_relay_status); // 动力电池负极继电器状态 1:接通 2:断开 其他:无效
|
|
|
|
//电池功率参数
|
|
j["ins_max_discharge_power"] = Json::Value(m_systemData->ins_max_discharge_power); // 仪表电池最大允许放电功率,单位:kW
|
|
j["dyn_max_discharge_power"] = Json::Value(m_systemData->dyn_max_discharge_power); // 动力电池最大允许放电功率,单位:kW
|
|
|
|
//电池SOC
|
|
j["ins_soc"] = Json::Value(m_systemData->ins_soc); // 仪表电池SOC,单位:%
|
|
j["dyn_soc"] = Json::Value(m_systemData->dyn_soc); // 动力电池SOC,单位:%
|
|
|
|
//电池能量
|
|
j["ins_total_energy"] = Json::Value(m_systemData->ins_total_energy); // 仪表电池能量,单位:kWh
|
|
j["dyn_total_energy"] = Json::Value(m_systemData->dyn_total_energy); // 动力电池能量,单位:kWh
|
|
|
|
//电池输入功率
|
|
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端电压,单位:V
|
|
j["ins_voltage_pack"] = Json::Value(m_systemData->ins_voltage_pack); // 仪表电池PACK端电压,单位:V
|
|
j["ins_current"] = Json::Value(m_systemData->ins_current); // 仪表电池电流,单位:A
|
|
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端电压,单位:V
|
|
j["dyn_voltage_pack"] = Json::Value(m_systemData->dyn_voltage_pack); // 动力电池PACK端电压,单位:V
|
|
j["dyn_current"] = Json::Value(m_systemData->dyn_current); // 动力电池电流,单位:A
|
|
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); // 紧急状态
|
|
j["dyn_emergency_status"] = Json::Value(m_systemData->dyn_emergency_status); // 紧急状态
|
|
|
|
// 电池充电等级和漏水状态
|
|
j["dyn_charge_level"] = Json::Value(m_systemData->dyn_charge_level); //01H:1级(不限)02H:2级(限功率)03H:3级(关闭)
|
|
j["water_leak_status_from_insbat"] = Json::Value(m_systemData->water_leak_status_from_insbat ); // 00 正常,01 异常漏水
|
|
j["water_leak_status_from_dynbat"] = Json::Value((m_systemData->water_leak_status_from_dynbat) ); // 00 正常,01 异常漏水
|
|
j["dcdc_status_from_insbat"] = Json::Value((m_systemData->dcdc_status_from_insbat ) ); // 00 正常,01 故障
|
|
|
|
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功率限制值
|
|
|
|
// uint8_t ins_charge_status; // 仪表电池充放电状态:00H-无效,10H-充电,20H-放电
|
|
// uint8_t dyn_charge_status; // 动力电池充放电状态:00H-无效,10H-充电,20H-放电
|
|
j["ins_charge_status"] = Json::Value(m_systemData->ins_charge_status);
|
|
j["dyn_charge_status"] = Json::Value(m_systemData->dyn_charge_status);
|
|
|
|
//设备在线状态
|
|
j["device_online"]["device_online_flag1"] = Json::Value(m_systemData->device_online_flag1);
|
|
j["device_online"]["device_online_flag2"] = Json::Value(m_systemData->device_online_flag2);
|
|
|
|
j["device_online_status"]["ins_online_state"] = Json::Value(m_systemData->device_online_status.ins_online_state); // 仪表锂电在线标志位
|
|
j["device_online_status"]["dyn_online_state"] = Json::Value(m_systemData->device_online_status.dyn_online_state); // 动力锂电在线标志位
|
|
j["device_online_status"]["fuel_online_state"] = Json::Value(m_systemData->device_online_status.fuel_online_state); // 燃电锂电在线标志位
|
|
j["device_online_status"]["high_voltage_online_state"] = Json::Value(m_systemData->device_online_status.high_voltage_online_state); // 高压配电板在线标志位
|
|
j["device_online_status"]["low_voltage_online_state"] = Json::Value(m_systemData->device_online_status.low_voltage_online_state); // 低压配电板在线标志位
|
|
j["device_online_status"]["composite_online_state"] = Json::Value(m_systemData->device_online_status.composite_online_state); // 复合管控主机在线标志位
|
|
j["device_online_status"]["composite_backup_online_state"] = Json::Value(m_systemData->device_online_status.composite_backup_online_state); // 复合管控备机在线标志位
|
|
// cout << j << endl;
|
|
//通信状态
|
|
//ccu状态
|
|
j["comm_state"]["ccu_status"]["isTimeout"] = Json::Value(m_systemData->device_common_status.ccu_status.isTimeout);
|
|
j["comm_state"]["ccu_status"]["lastUpdateTime"] = Json::Value(m_systemData->device_common_status.ccu_status.lastUpdateTime);
|
|
|
|
//高压配电状态
|
|
j["comm_state"]["dis_hv_c1"]["isTimeout"] = Json::Value(m_systemData->device_common_status.dis_hv_c1.isTimeout);
|
|
j["comm_state"]["dis_hv_c1"]["lastUpdateTime"] = Json::Value(m_systemData->device_common_status.dis_hv_c1.lastUpdateTime);
|
|
j["comm_state"]["dis_hv_c2"]["isTimeout"] = Json::Value(m_systemData->device_common_status.dis_hv_c2.isTimeout);
|
|
j["comm_state"]["dis_hv_c2"]["lastUpdateTime"] = Json::Value(m_systemData->device_common_status.dis_hv_c2.lastUpdateTime);
|
|
|
|
//低压配电状态
|
|
j["comm_state"]["dis_lv_c1"]["isTimeout"] = Json::Value(m_systemData->device_common_status.dis_lv_c1.isTimeout);
|
|
j["comm_state"]["dis_lv_c1"]["lastUpdateTime"] = Json::Value(m_systemData->device_common_status.dis_lv_c1.lastUpdateTime);
|
|
j["comm_state"]["dis_lv_c2"]["isTimeout"] = Json::Value(m_systemData->device_common_status.dis_lv_c2.isTimeout);
|
|
j["comm_state"]["dis_lv_c2"]["lastUpdateTime"] = Json::Value(m_systemData->device_common_status.dis_lv_c2.lastUpdateTime);
|
|
|
|
// 低压配电状态
|
|
j["comm_state"]["dis_lv_c1"]["isTimeout"] = Json::Value(m_systemData->device_common_status.dis_lv_c1.isTimeout);
|
|
j["comm_state"]["dis_lv_c1"]["lastUpdateTime"] = Json::Value(m_systemData->device_common_status.dis_lv_c1.lastUpdateTime);
|
|
j["comm_state"]["dis_lv_c2"]["isTimeout"] = Json::Value(m_systemData->device_common_status.dis_lv_c2.isTimeout);
|
|
j["comm_state"]["dis_lv_c2"]["lastUpdateTime"] = Json::Value(m_systemData->device_common_status.dis_lv_c2.lastUpdateTime);
|
|
|
|
//复合管控器心跳计算器
|
|
j["heartbeat"] = Json::Value(m_systemData->heartbeat);
|
|
//=============================================================================================================
|
|
//配电器状态
|
|
//动力母线状态
|
|
j["power_bus_status"]["fuelCellCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.fuelCellCircuitBreaker); // 燃料电池断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["powerLithiumBatteryCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.powerLithiumBatteryCircuitBreaker); // 动力锂电池断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["propulsionMotorCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.propulsionMotorCircuitBreaker); // 推进电机断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["lithiumBatteryGroupInstrumentCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.lithiumBatteryGroupInstrumentCircuitBreaker); // 锂电池组仪表断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["dcDc5ModuleCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.dcDc5ModuleCircuitBreaker); // DC/DC5模块断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["bowHighVoltageDistributionBoxCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.bowHighVoltageDistributionBoxCircuitBreaker); // 艏部高压配电箱断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["sternFTDevice45CircuitBreaker"] = Json::Value(m_systemData->power_bus_status.sternFTDevice45CircuitBreaker); // 艉部FT装置4/5断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["sternRudderSwitch1CircuitBreaker"] = Json::Value(m_systemData->power_bus_status.sternRudderSwitch1CircuitBreaker); // 艉舵开关1断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["sternRudderSwitch2CircuitBreaker"] = Json::Value(m_systemData->power_bus_status.sternRudderSwitch2CircuitBreaker); // 艉舵开关2断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["fbReservedCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.fbReservedCircuitBreaker); // FB预留断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["tyzReservedCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.tyzReservedCircuitBreaker); // TYZ预留断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["reservedCircuitBreaker"] = Json::Value(m_systemData->power_bus_status.reservedCircuitBreaker); // 预留断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_bus_status"]["dcDcModuleStatus"] = Json::Value(m_systemData->power_bus_status.dcDcModuleStatus); // DC/DC5模块状态: 0-未运行 1-运行 2-过温关机 3-输出过流 4-输出过压 5-输出欠压 6-输入过压 7-输入欠压 8-输出短路 9-内部故障
|
|
j["power_bus_status"]["coolingSystemStatus"] = Json::Value(m_systemData->power_bus_status.coolingSystemStatus); // 冷却系统状态: 0-未运行 1-运行 2-冷却泵1故障 3-冷却泵2故障 4-冷却水泄露
|
|
j["power_bus_status"]["powerBusInsulationStatus"] = Json::Value(m_systemData->power_bus_status.powerBusInsulationStatus); // 动力母排绝缘状态: 0-正常 1-绝缘低
|
|
j["power_bus_status"]["aBusInsulationStatus"] = Json::Value(m_systemData->power_bus_status.aBusInsulationStatus); // A汇流排绝缘状态: 0-正常 1-绝缘低
|
|
j["power_bus_status"]["meterPowerLossSignal"] = Json::Value(m_systemData->power_bus_status.meterPowerLossSignal); // 仪表电源状态: 0-正常 1-故障
|
|
j["power_bus_status"]["emergencyPowerLossSignal"] = Json::Value(m_systemData->power_bus_status.emergencyPowerLossSignal); // 应急电源状态: 0-正常 1-故障
|
|
j["power_bus_status"]["dcDcTemperature"] = Json::Value(m_systemData->power_bus_status.dcDcTemperature); // DC/DC模块温度
|
|
j["power_bus_status"]["powerBusVoltage"] = Json::Value(m_systemData->power_bus_status.powerBusVoltage); // 动力汇流排电压
|
|
j["power_bus_status"]["dcDc5ModuleCurrent"] = Json::Value(m_systemData->power_bus_status.dcDc5ModuleCurrent); // DC/DC5模块电流
|
|
j["power_bus_status"]["powerBusCurrent"] = Json::Value(m_systemData->power_bus_status.powerBusCurrent); // 动力汇流排电流
|
|
j["power_bus_status"]["busbarAVoltage"] = Json::Value(m_systemData->power_bus_status.busbarAVoltage); // A汇流排电压
|
|
j["power_bus_status"]["propulsionMotorControlBoxCurrent"] = Json::Value(m_systemData->power_bus_status.propulsionMotorControlBoxCurrent); // 推进电机控制箱电流
|
|
j["power_bus_status"]["busbarACurrent"] = Json::Value(m_systemData->power_bus_status.busbarACurrent); // A汇流排电流
|
|
j["power_bus_status"]["lithiumBatteryGroupMeterCurrent"] = Json::Value(m_systemData->power_bus_status.lithiumBatteryGroupMeterCurrent); // 锂电池组(仪表)电流
|
|
j["power_bus_status"]["bowHighVoltageDistributionBoxCurrent"] = Json::Value(m_systemData->power_bus_status.bowHighVoltageDistributionBoxCurrent); // 艏部高压配电箱电流
|
|
j["power_bus_status"]["sternFTDevice45Current"] = Json::Value(m_systemData->power_bus_status.sternFTDevice45Current); // 艉部FT装置4/5电流
|
|
j["power_bus_status"]["tyzReservedSwitchCurrent"] = Json::Value(m_systemData->power_bus_status.tyzReservedSwitchCurrent); // TYZ预留开关电流
|
|
j["power_bus_status"]["sternRudderSwitch1Current"] = Json::Value(m_systemData->power_bus_status.sternRudderSwitch1Current); // 艉舵开关1电流
|
|
j["power_bus_status"]["reservedCurrent1"] = Json::Value(m_systemData->power_bus_status.reservedCurrent1); // 预留电流1
|
|
j["power_bus_status"]["sternRudderSwitch2Current"] = Json::Value(m_systemData->power_bus_status.sternRudderSwitch2Current); // 艉舵开关2电流
|
|
j["power_bus_status"]["reservedCurrent2"] = Json::Value(m_systemData->power_bus_status.reservedCurrent2); // 预留电流2
|
|
j["power_bus_status"]["fbReservedSwitchCurrent"] = Json::Value(m_systemData->power_bus_status.fbReservedSwitchCurrent); // FB预留电流
|
|
j["power_bus_status"]["reservedCurrent3"] = Json::Value(m_systemData->power_bus_status.reservedCurrent3); // 预留电流3
|
|
j["power_bus_status"]["coolWaterPressure"] = Json::Value(m_systemData->power_bus_status.coolWaterPressure); // 冷却水压力
|
|
|
|
|
|
//应急电池信息
|
|
j["emergency_battery1"]["voltage"] = Json::Value(m_systemData->emergency_battery1_voltage); // 应急电池1总电压 [V]
|
|
j["emergency_battery1"]["current"] = Json::Value(m_systemData->emergency_battery1_current); // 应急电池1总电流 [A]
|
|
j["emergency_battery1"]["max_temp"] = Json::Value(m_systemData->emergency_battery1_max_temp); // 应急电池1最高温度 [°C]
|
|
j["emergency_battery1"]["fault_word"] = Json::Value(m_systemData->emergency_battery1_fault_word); // 应急电池1故障字
|
|
|
|
j["emergency_battery2"]["voltage"] = Json::Value(m_systemData->emergency_battery2_voltage); // 应急电池2总电压 [V]
|
|
j["emergency_battery2"]["current"] = Json::Value(m_systemData->emergency_battery2_current); // 应急电池2总电流 [A]
|
|
j["emergency_battery2"]["max_temp"] = Json::Value(m_systemData->emergency_battery2_max_temp); // 应急电池2最高温度 [°C]
|
|
j["emergency_battery2"]["fault_word"] = Json::Value(m_systemData->emergency_battery2_fault_word); // 应急电池2故障字
|
|
|
|
|
|
//应急电池
|
|
// emergency_battery1_voltage = data.emergency_battery1_voltage * 0.1;
|
|
// emergency_battery1_current = data.emergency_battery1_current * 0.05;
|
|
// emergency_battery1_max_temp = data.emergency_battery1_max_temp * 0.1;
|
|
// emergency_battery1_fault_word = data.emergency_battery1_fault_word;
|
|
// emergency_battery2_voltage = data.emergency_battery2_voltage * 0.1;
|
|
// emergency_battery2_current = data.emergency_battery2_current * 0.05;
|
|
// emergency_battery2_max_temp = data.emergency_battery2_max_temp * 0.1;
|
|
// emergency_battery2_fault_word = data.emergency_battery2_fault_word;
|
|
|
|
|
|
// union {
|
|
// unsigned char lowFaultWord;
|
|
// struct {
|
|
// bool overTemperatureShutdown : 1; // Bit0: DC/DC模块过温关机
|
|
// bool outputOverCurrent : 1; // Bit1: 输出过流
|
|
// bool outputOverVoltage : 1; // Bit2: 输出过压
|
|
// bool outputUnderVoltage : 1; // Bit3: 输出欠压
|
|
// bool inputOverVoltage : 1; // Bit4: 输入过压
|
|
// bool inputUnderVoltage : 1; // Bit5: 输入欠压
|
|
// bool outputShortCircuit : 1; // Bit6: 输出短路保护
|
|
// bool internalFault : 1; // Bit7: 内部故障
|
|
// };
|
|
// };
|
|
// // DC/DC5故障字高
|
|
// union {
|
|
// unsigned char highFaultWord;
|
|
// struct {
|
|
// bool communicationFault : 1; // Bit0: 通讯故障报警
|
|
// bool workingStatus : 1; // Bit1: 工作状态(1:启动, 0:关闭)
|
|
// bool coolingPump1Fault : 1; // Bit2: 冷却泵1故障
|
|
// bool coolingPump2Fault : 1; // Bit3: 冷却泵2故障
|
|
// bool coolingWaterLeak : 1; // Bit4: 冷却水泄露
|
|
// bool coolingPump1Running : 1; // Bit5: 冷却泵1运行状态
|
|
// bool coolingPump2Running : 1; // Bit6: 冷却泵2运行状态
|
|
// bool reserved : 1; // Bit7: 保留位
|
|
// };
|
|
// };
|
|
j["power_bus_status"]["dcdcStatus1"] = Json::Value(m_systemData->m_dcdcStatus.lowFaultWord);
|
|
j["power_bus_status"]["dcdcStatus2"] = Json::Value(m_systemData->m_dcdcStatus.highFaultWord);
|
|
|
|
//动力母线A状态
|
|
j["power_a_bus_status"]["bowFTDevice123CircuitBreaker"] = Json::Value(m_systemData->power_a_bus_status.bowFTDevice123CircuitBreaker); // 艏部FT装置1/2/3断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_a_bus_status"]["actuatorCircuitBreaker"] = Json::Value(m_systemData->power_a_bus_status.actuatorCircuitBreaker); // 启闭机构断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_a_bus_status"]["mastSteeringGearControlBoxCircuitBreaker"] = Json::Value(m_systemData->power_a_bus_status.mastSteeringGearControlBoxCircuitBreaker); // 桅杆舵机控制箱断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_a_bus_status"]["xczCircuitBreaker"] = Json::Value(m_systemData->power_a_bus_status.xczCircuitBreaker); // XCZ断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_a_bus_status"]["bowRudderControlBoxCircuitBreaker"] = Json::Value(m_systemData->power_a_bus_status.bowRudderControlBoxCircuitBreaker); // 艏舵控制箱断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_a_bus_status"]["openWaterCoverStartCylinderCircuitBreaker"] = Json::Value(m_systemData->power_a_bus_status.openWaterCoverStartCylinderCircuitBreaker); // 敞水盖启动电缸断路器状态: 0-断开 1-闭合 2-故障
|
|
j["power_a_bus_status"]["instrumentPowerFailureSignal"] = Json::Value(m_systemData->power_a_bus_status.instrumentPowerFailureSignal); // 仪表电源失电信号: 0-正常 1-故障
|
|
j["power_a_bus_status"]["emergencyPowerFailureSignal"] = Json::Value(m_systemData->power_a_bus_status.emergencyPowerFailureSignal); // 应急电源失电信号: 0-正常 1-故障
|
|
j["power_a_bus_status"]["waterIngressionAlarm"] = Json::Value(m_systemData->power_a_bus_status.waterIngressionAlarm); // 浸水报警: 0-无 1-有
|
|
j["power_a_bus_status"]["busbarBVoltage"] = Json::Value(m_systemData->power_a_bus_status.busbarBVoltage); // 汇流排B电压
|
|
j["power_a_bus_status"]["busbarBCurrent"] = Json::Value(m_systemData->power_a_bus_status.busbarBCurrent); // 汇流排B电流
|
|
j["power_a_bus_status"]["bowFTDevice123Current"] = Json::Value(m_systemData->power_a_bus_status.bowFTDevice123Current); // 艏部FT装置1/2/3电流
|
|
j["power_a_bus_status"]["actuatorCurrent"] = Json::Value(m_systemData->power_a_bus_status.actuatorCurrent); // 启闭机构电流
|
|
j["power_a_bus_status"]["mastSteeringGearControlBoxCurrent"] = Json::Value(m_systemData->power_a_bus_status.mastSteeringGearControlBoxCurrent); // 桅杆舵机控制箱电流
|
|
j["power_a_bus_status"]["xczCurrent"] = Json::Value(m_systemData->power_a_bus_status.xczCurrent); // XCZ电流
|
|
j["power_a_bus_status"]["bowRudderControlBoxCurrent"] = Json::Value(m_systemData->power_a_bus_status.bowRudderControlBoxCurrent); // 艏舵控制箱电流
|
|
j["power_a_bus_status"]["openWaterCoverStartCylinderCurrent"] = Json::Value(m_systemData->power_a_bus_status.openWaterCoverStartCylinderCurrent); // 敞水盖启动电缸电流
|
|
|
|
//仪表主母线状态
|
|
j["instrument_main_bus_status"]["lithiumBatteryGroupInstrumentCircuitBreaker"] = Json::Value(m_systemData->instrument_main_bus_status.lithiumBatteryGroupInstrumentCircuitBreaker); // 锂电池组(仪表)断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_main_bus_status"]["bowLowVoltageDistributionBoxCircuitBreaker"] = Json::Value(m_systemData->instrument_main_bus_status.bowLowVoltageDistributionBoxCircuitBreaker); // 艏部低压配电箱断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_main_bus_status"]["unit4InstrumentDC48VCircuitBreaker"] = Json::Value(m_systemData->instrument_main_bus_status.unit4InstrumentDC48VCircuitBreaker); // UNIT4仪表DC48V断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_main_bus_status"]["dcC1DCDistributionPanelCircuitBreaker"] = Json::Value(m_systemData->instrument_main_bus_status.dcC1DCDistributionPanelCircuitBreaker); // DC-C1直流配电板断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_main_bus_status"]["reservedCircuitBreaker1"] = Json::Value(m_systemData->instrument_main_bus_status.reservedCircuitBreaker1); // 预留断路器1状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_main_bus_status"]["reservedCircuitBreaker2"] = Json::Value(m_systemData->instrument_main_bus_status.reservedCircuitBreaker2); // 预留断路器2状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_main_bus_status"]["emergencyLithiumBatteryGroup2CircuitBreaker"] = Json::Value(m_systemData->instrument_main_bus_status.emergencyLithiumBatteryGroup2CircuitBreaker); // 应急锂电池组2断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_main_bus_status"]["instrumentPowerFailureSignal"] = Json::Value(m_systemData->instrument_main_bus_status.instrumentPowerFailureSignal); // 仪表电源失电信号: 0-正常 1-故障
|
|
j["instrument_main_bus_status"]["emergencyPowerFailureSignal"] = Json::Value(m_systemData->instrument_main_bus_status.emergencyPowerFailureSignal); // 应急电源失电信号: 0-正常 1-故障
|
|
j["instrument_main_bus_status"]["instrumentBusbarInsulationLow"] = Json::Value(m_systemData->instrument_main_bus_status.instrumentBusbarInsulationLow); // 仪表汇流排绝缘低: 0-正常 1-绝缘低
|
|
j["instrument_main_bus_status"]["instrumentBusbarVoltage"] = Json::Value(m_systemData->instrument_main_bus_status.instrumentBusbarVoltage); // 仪表母排电压
|
|
j["instrument_main_bus_status"]["bowLowVoltageDistributionBoxCurrent"] = Json::Value(m_systemData->instrument_main_bus_status.bowLowVoltageDistributionBoxCurrent); // 艏部低压配电箱电流
|
|
j["instrument_main_bus_status"]["dcC1InstrumentDC48VCurrent"] = Json::Value(m_systemData->instrument_main_bus_status.dcC1InstrumentDC48VCurrent); // DC-C1(直流配电板1)仪表DC48V电流
|
|
j["instrument_main_bus_status"]["reservedCurrent1"] = Json::Value(m_systemData->instrument_main_bus_status.reservedCurrent1); // 预留电流1
|
|
j["instrument_main_bus_status"]["emergencyLithiumBatteryGroup2Current"] = Json::Value(m_systemData->instrument_main_bus_status.emergencyLithiumBatteryGroup2Current); // 应急锂电池组2电流
|
|
j["instrument_main_bus_status"]["lithiumBatteryGroupInstrumentCurrent"] = Json::Value(m_systemData->instrument_main_bus_status.lithiumBatteryGroupInstrumentCurrent); // 锂电池组(仪表)电流
|
|
j["instrument_main_bus_status"]["unit4InstrumentDC48VCurrent"] = Json::Value(m_systemData->instrument_main_bus_status.unit4InstrumentDC48VCurrent); // UNIT4仪表DC48V电流
|
|
j["instrument_main_bus_status"]["reservedCurrent2"] = Json::Value(m_systemData->instrument_main_bus_status.reservedCurrent2); // 预留电流2
|
|
j["instrument_main_bus_status"]["emergency2BusbarVoltage"] = Json::Value(m_systemData->instrument_main_bus_status.emergency2BusbarVoltage); // 应急2汇流排电压
|
|
j["instrument_main_bus_status"]["compositeEnergyManagementSystemEmergencyDC48VCurrent"] = Json::Value(m_systemData->instrument_main_bus_status.compositeEnergyManagementSystemEmergencyDC48VCurrent); // 复合能源管控系统应急DC48V电流
|
|
j["instrument_main_bus_status"]["fuelCellSecuritySystemEmergencyDC48VCurrent"] = Json::Value(m_systemData->instrument_main_bus_status.fuelCellSecuritySystemEmergencyDC48VCurrent); // 燃料电池安全系统应急DC48V电流
|
|
j["instrument_main_bus_status"]["plcControlPowerCurrent"] = Json::Value(m_systemData->instrument_main_bus_status.plcControlPowerCurrent); // PLC控制电源电流
|
|
|
|
//仪表母线状态
|
|
j["instrument_bus_status"]["unit1CircuitBreaker"] = Json::Value(m_systemData->instrument_bus_status.unit1CircuitBreaker); // UNIT1断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["unit2CircuitBreaker"] = Json::Value(m_systemData->instrument_bus_status.unit2CircuitBreaker); // UNIT2断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["unit3CircuitBreaker"] = Json::Value(m_systemData->instrument_bus_status.unit3CircuitBreaker); // UNIT3断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["unit5CircuitBreaker"] = Json::Value(m_systemData->instrument_bus_status.unit5CircuitBreaker); // UNIT5断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["bowPZDeviceCircuitBreaker"] = Json::Value(m_systemData->instrument_bus_status.bowPZDeviceCircuitBreaker); // 艏部PZ装置断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["reservedCircuitBreaker1"] = Json::Value(m_systemData->instrument_bus_status.reservedCircuitBreaker1); // 预留断路器1状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["reservedCircuitBreaker2"] = Json::Value(m_systemData->instrument_bus_status.reservedCircuitBreaker2); // 预留断路器2状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["emergencyLithiumBatteryGroup1CircuitBreaker"] = Json::Value(m_systemData->instrument_bus_status.emergencyLithiumBatteryGroup1CircuitBreaker); // 应急锂电池组1断路器状态: 0-断开 1-闭合 2-故障
|
|
j["instrument_bus_status"]["powerFailureSignal"] = Json::Value(m_systemData->instrument_bus_status.powerFailureSignal); // 仪表电源失电信号: 0-正常 1-故障
|
|
j["instrument_bus_status"]["emergencyPowerFailureSignal"] = Json::Value(m_systemData->instrument_bus_status.emergencyPowerFailureSignal); // 应急电源失电信号: 0-正常 1-故障
|
|
j["instrument_bus_status"]["waterIngressionAlarm"] = Json::Value(m_systemData->instrument_bus_status.waterIngressionAlarm); // 浸水报警: 0-无 1-有
|
|
j["instrument_bus_status"]["instrumentBusbarVoltage"] = Json::Value(m_systemData->instrument_bus_status.instrumentBusbarVoltage); // 仪表母排电压
|
|
j["instrument_bus_status"]["instrumentBusbarCurrent"] = Json::Value(m_systemData->instrument_bus_status.instrumentBusbarCurrent); // 仪表母排电流
|
|
j["instrument_bus_status"]["unit1Current"] = Json::Value(m_systemData->instrument_bus_status.unit1Current); // UNIT1电流
|
|
j["instrument_bus_status"]["unit2Current"] = Json::Value(m_systemData->instrument_bus_status.unit2Current); // UNIT2电流
|
|
j["instrument_bus_status"]["unit3Current"] = Json::Value(m_systemData->instrument_bus_status.unit3Current); // UNIT3电流
|
|
j["instrument_bus_status"]["unit5Current"] = Json::Value(m_systemData->instrument_bus_status.unit5Current); // UNIT5电流
|
|
j["instrument_bus_status"]["bowPZDeviceCurrent"] = Json::Value(m_systemData->instrument_bus_status.bowPZDeviceCurrent); // 艏部PZ装置电流
|
|
j["instrument_bus_status"]["emergencyLithiumBatteryGroup1Current"] = Json::Value(m_systemData->instrument_bus_status.emergencyLithiumBatteryGroup1Current); // 应急锂电池组1电流
|
|
j["instrument_bus_status"]["emergency1BusbarVoltage"] = Json::Value(m_systemData->instrument_bus_status.emergency1BusbarVoltage); // 应急1汇流排电压
|
|
|
|
|
|
//MOOSDB数据
|
|
j["moosdb"]["appFreq"] = Json::Value(m_powerManger->GetPublicAppFreq());
|
|
j["moosdb"]["commFreq"] = Json::Value(m_powerManger->GetPublicCommsFreq());
|
|
j["moosdb"]["startTime"] = Json::Value(m_powerManger->GetPublicAppStartTime());
|
|
j["moosdb"]["cpuLoad"] = Json::Value(m_powerManger->GetPublicCPULoad());
|
|
j["moosdb"]["timeSinceIterate"] = Json::Value(m_powerManger->GetPublicTimeSinceIterate());
|
|
j["moosdb"]["lastIterateTime"] = Json::Value(m_powerManger->GetPublicLastIterateTime());
|
|
j["moosdb"]["lastIterateCount"] = Json::Value(m_powerManger->GetPublicIterateCount());
|
|
j["moosdb"]["serverHost"] = Json::Value(m_powerManger->GetServerHost());
|
|
j["moosdb"]["serverPort"] = Json::Value(m_powerManger->GetServerPort());
|
|
|
|
|
|
// degub
|
|
#ifdef _DEBUG
|
|
//订阅消息
|
|
j["debug"]["m_secdistStateMsg_fb_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_secdistStateMsg_fb_debug.first);
|
|
j["debug"]["m_secdistStateMsg_fb_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_secdistStateMsg_fb_debug.second);
|
|
|
|
j["debug"]["m_equStateMsg_cmd_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_equStateMsg_cmd_debug.first);
|
|
j["debug"]["m_equStateMsg_cmd_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_equStateMsg_cmd_debug.second);
|
|
|
|
j["debug"]["m_depthMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_depthMsg_st_debug.first);
|
|
j["debug"]["m_depthMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_depthMsg_st_debug.second);
|
|
|
|
j["debug"]["m_setOpConditionMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_setOpConditionMsg_st_debug.first);
|
|
j["debug"]["m_setOpConditionMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_setOpConditionMsg_st_debug.second);
|
|
|
|
j["debug"]["m_setOpModeMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_setOpModeMsg_st_debug.first);
|
|
j["debug"]["m_setOpModeMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_setOpModeMsg_st_debug.second);
|
|
|
|
j["debug"]["m_taskStartMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_taskStartMsg_st_debug.first);
|
|
j["debug"]["m_taskStartMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_taskStartMsg_st_debug.second);
|
|
|
|
j["debug"]["m_taskStopMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_taskStopMsg_st_debug.first);
|
|
j["debug"]["m_taskStopMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_taskStopMsg_st_debug.second);
|
|
|
|
j["debug"]["m_setDevSwitchMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_setDevSwitchMsg_st_debug.first);
|
|
j["debug"]["m_setDevSwitchMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_setDevSwitchMsg_st_debug.second);
|
|
|
|
j["debug"]["m_setPMSysMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_setPMSysMsg_st_debug.first);
|
|
j["debug"]["m_setPMSysMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_setPMSysMsg_st_debug.second);
|
|
|
|
j["debug"]["m_sysStateMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_sysStateMsg_st_debug.first);
|
|
j["debug"]["m_sysStateMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_sysStateMsg_st_debug.second);
|
|
|
|
//发布消息
|
|
j["debug"]["m_equInsStateMsg_fb_degub"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_equInsStateMsg_fb_degub.first);
|
|
j["debug"]["m_equInsStateMsg_fb_degub"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_equInsStateMsg_fb_degub.second);
|
|
|
|
j["debug"]["m_secdistStateMsg_cmd_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_secdistStateMsg_cmd_debug.first);
|
|
j["debug"]["m_secdistStateMsg_cmd_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_secdistStateMsg_cmd_debug.second);
|
|
|
|
j["debug"]["m_equStateMsg_fb_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_equStateMsg_fb_debug.first);
|
|
j["debug"]["m_equStateMsg_fb_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_equStateMsg_fb_debug.second);
|
|
|
|
j["debug"]["m_disSysStateMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_disSysStateMsg_st_debug.first);
|
|
j["debug"]["m_disSysStateMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_disSysStateMsg_st_debug.second);
|
|
|
|
j["debug"]["m_currentStateMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_currentStateMsg_st_debug.first);
|
|
j["debug"]["m_currentStateMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_currentStateMsg_st_debug.second);
|
|
|
|
j["debug"]["m_pmStateMsg_fb_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_pmStateMsg_fb_debug.first);
|
|
j["debug"]["m_pmStateMsg_fb_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_pmStateMsg_fb_debug.second);
|
|
|
|
j["debug"]["m_fcsStateMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_fcsStateMsg_st_debug.first);
|
|
j["debug"]["m_fcsStateMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_fcsStateMsg_st_debug.second);
|
|
|
|
j["debug"]["m_liBatStateMsg_st_debug"]["name"] = Json::Value(m_powerManger->m_upperCommManager->m_liBatStateMsg_st_debug.first);
|
|
j["debug"]["m_liBatStateMsg_st_debug"]["content"] = Json::Value(m_powerManger->m_upperCommManager->m_liBatStateMsg_st_debug.second);
|
|
#endif
|
|
|
|
j["ccuColCmd"]["fcmode"] = Json::Value(m_powerManger->m_CcuColCmd.fcmode);
|
|
j["ccuColCmd"]["fcuCmd"] = Json::Value(m_powerManger->m_CcuColCmd.fcuCmd);
|
|
j["ccuColCmd"]["fcuPowerEfficiency"] = Json::Value(m_powerManger->m_CcuColCmd.fcuPowerEfficiency);
|
|
j["ccuColCmd"]["insChargeEnable"] = Json::Value(m_powerManger->m_CcuColCmd.insChargeEnable);
|
|
j["ccuColCmd"]["insBatCmd"] = Json::Value(m_powerManger->m_CcuColCmd.insBatCmd);
|
|
j["ccuColCmd"]["powerBatCmd"] = Json::Value(m_powerManger->m_CcuColCmd.powerBatCmd);
|
|
j["ccuColCmd"]["powerBatEfficiency"] = Json::Value(m_powerManger->m_CcuColCmd.powerBatEfficiency);
|
|
j["ccuColCmd"]["heartbeat"] = Json::Value(m_powerManger->m_CcuColCmd.heartbeat);
|
|
j["ccuColCmd"]["masterState"] = Json::Value(m_powerManger->m_CcuColCmd.masterState);
|
|
|
|
// 时间戳
|
|
j["timestamp"] = Json::Value((Json::UInt64)(std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
std::chrono::system_clock::now().time_since_epoch()).count()));
|
|
|
|
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_) {
|
|
if (c->send.len > MAX_WS_BACKLOG) {
|
|
continue;
|
|
}
|
|
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_;
|
|
}
|
|
|
|
void HttpServer::handleLogRequest(struct mg_connection* c, const std::string& msg) {
|
|
try {
|
|
Json::Value json;
|
|
Json::CharReaderBuilder builder;
|
|
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
|
|
const char* msg_cstr = msg.c_str();
|
|
std::string errors;
|
|
|
|
if (!reader->parse(msg_cstr, msg_cstr + msg.size(), &json, &errors)) {
|
|
LOG_F(ERROR, "Failed to parse log request JSON: %s", errors.c_str());
|
|
return;
|
|
}
|
|
|
|
std::string type = json["type"].asString();
|
|
if (type == "get_logs") {
|
|
int page = json["page"].asInt();
|
|
int pageSize = json["pageSize"].asInt();
|
|
std::string level = json["filter"]["level"].asString();
|
|
std::string search = json["filter"]["search"].asString();
|
|
bool reverse = json["reverse"].asBool(); // 新增参数,控制是否倒序显示
|
|
|
|
auto logs = readLogFile(page, pageSize, level, search);
|
|
|
|
Json::Value response;
|
|
response["type"] = "log";
|
|
response["page"] = page;
|
|
response["pageSize"] = pageSize;
|
|
response["total"] = logs.size(); // 返回总条数
|
|
response["content"] = Json::arrayValue;
|
|
|
|
if (reverse) {
|
|
// 如果需要倒序,反转日志顺序
|
|
for (auto it = logs.rbegin(); it != logs.rend(); ++it) {
|
|
response["content"].append(*it);
|
|
}
|
|
} else {
|
|
// 否则按原顺序返回
|
|
for (const auto& log : logs) {
|
|
response["content"].append(log);
|
|
}
|
|
}
|
|
|
|
Json::StreamWriterBuilder builder;
|
|
std::string responseStr = Json::writeString(builder, response);
|
|
mg_ws_send(c, responseStr.c_str(), responseStr.size(), WEBSOCKET_OP_TEXT);
|
|
}
|
|
} catch (const std::exception& e) {
|
|
LOG_F(ERROR, "Error handling log request: %s", e.what());
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> HttpServer::readLogFile(int page, int pageSize, const std::string& level, const std::string& search) {
|
|
std::vector<std::string> logs;
|
|
std::ifstream file(m_logFilePath);
|
|
if (!file.is_open()) {
|
|
LOG_F(ERROR, "Failed to open log file: %s", m_logFilePath.c_str());
|
|
return logs;
|
|
}
|
|
|
|
// 获取文件大小
|
|
file.seekg(0, std::ios::end);
|
|
std::streampos fileSize = file.tellg();
|
|
file.seekg(0, std::ios::beg);
|
|
|
|
std::string line;
|
|
std::vector<std::string> filteredLogs;
|
|
|
|
// 读取并过滤所有行
|
|
while (std::getline(file, line)) {
|
|
// 过滤日志级别和搜索内容
|
|
if ((level.empty() || level == "ALL" || line.find(level) != std::string::npos) &&
|
|
(search.empty() || line.find(search) != std::string::npos)) {
|
|
filteredLogs.push_back(line);
|
|
}
|
|
}
|
|
|
|
// 计算总页数
|
|
int totalLines = filteredLogs.size();
|
|
|
|
// 如果没有内容,直接返回空
|
|
if (totalLines == 0) {
|
|
return logs;
|
|
}
|
|
|
|
// 计算当前页的起始和结束索引
|
|
int start = std::max(0, totalLines - (page * pageSize));
|
|
int end = std::max(0, totalLines - ((page - 1) * pageSize));
|
|
|
|
// 返回当前页的日志(已经是倒序的)
|
|
return std::vector<std::string>(filteredLogs.begin() + start, filteredLogs.begin() + end);
|
|
}
|
|
|
|
void HttpServer::handleTestPage(struct mg_connection* c, const std::string& msg) {
|
|
try {
|
|
// 检查空消息
|
|
if (msg.empty()) {
|
|
LOG_F(ERROR, "Empty test page request received");
|
|
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
|
|
"{\"success\": false, \"error\": \"Empty request body\"}");
|
|
return;
|
|
}
|
|
|
|
// 解析JSON请求
|
|
Json::Value json;
|
|
Json::CharReaderBuilder builder;
|
|
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
|
|
std::string errors;
|
|
const char* msg_start = msg.c_str();
|
|
const char* msg_end = msg_start + msg.size();
|
|
|
|
if (!reader->parse(msg_start, msg_end, &json, &errors)) {
|
|
// 记录详细的解析错误
|
|
LOG_F(ERROR, "Failed to parse test page request JSON: %s\nRequest content: %s",
|
|
errors.c_str(), msg.c_str());
|
|
|
|
// 返回结构化的错误响应
|
|
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
|
|
"{\"success\": false, \"error\": \"Invalid JSON format\", "
|
|
"\"details\": \"%s\", \"position\": %d}",
|
|
errors.c_str(), (int)(errors.find("offset") != std::string::npos ?
|
|
std::stoi(errors.substr(errors.find("offset") + 7)) : 0));
|
|
return;
|
|
}
|
|
|
|
// 记录接收到的请求
|
|
LOG_F(INFO, "Received valid test page request: %s", msg.c_str());
|
|
|
|
// 检查必需字段是否存在
|
|
if (!json.isMember("type") || !json.isMember("id")) {
|
|
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
|
|
"{\"success\": false, \"error\": \"type and id fields are required\"}");
|
|
return;
|
|
}
|
|
unsigned int type = 0;
|
|
unsigned int id = 0;
|
|
|
|
try {
|
|
if (json["type"].isString()) {
|
|
type = std::stoul(json["type"].asString());
|
|
} else if (json["type"].isNumeric()) {
|
|
type = json["type"].asUInt();
|
|
} else {
|
|
throw std::invalid_argument("type must be number or numeric string");
|
|
}
|
|
|
|
if (json["id"].isString()) {
|
|
id = std::stoul(json["id"].asString());
|
|
} else if (json["id"].isNumeric()) {
|
|
id = json["id"].asUInt();
|
|
} else {
|
|
throw std::invalid_argument("id must be number or numeric string");
|
|
}
|
|
} catch (const std::exception& e) {
|
|
mg_http_reply(c, 400, "Content-Type: application/json\r\n",
|
|
"{\"success\": false, \"error\": \"%s\"}", e.what());
|
|
return;
|
|
}
|
|
|
|
m_powerManger->injectFault(type, id);
|
|
// 返回成功响应
|
|
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
|
|
"{\"success\": true, \"message\": \"Request received\", "
|
|
"\"content\": %s}",
|
|
msg.c_str());
|
|
} catch (const std::exception& e) {
|
|
LOG_F(ERROR, "Error handling test page request: %s", e.what());
|
|
mg_http_reply(c, 500, "Content-Type: text/plain\r\n", "Internal server error");
|
|
}
|
|
}
|
|
|
|
void HttpServer::monitorLogFile() {
|
|
static std::streampos lastPos = 0;
|
|
std::ifstream file(m_logFilePath);
|
|
|
|
if (!file.is_open()) {
|
|
LOG_F(ERROR, "Failed to open log file for monitoring: %s", m_logFilePath.c_str());
|
|
return;
|
|
}
|
|
|
|
// 获取文件大小
|
|
file.seekg(0, std::ios::end);
|
|
std::streampos currentPos = file.tellg();
|
|
|
|
// 如果文件大小没有变化,直接返回
|
|
if (currentPos == lastPos) {
|
|
return;
|
|
}
|
|
|
|
// 如果是第一次读取或文件被截断,从头开始读
|
|
if (currentPos < lastPos) {
|
|
lastPos = 0;
|
|
}
|
|
|
|
// 移动到上次读取的位置
|
|
file.seekg(lastPos);
|
|
|
|
std::string line;
|
|
std::vector<std::string> newLogs;
|
|
|
|
// 读取新的日志行
|
|
while (std::getline(file, line)) {
|
|
newLogs.push_back(line);
|
|
}
|
|
|
|
// 更新最后读取位置
|
|
lastPos = currentPos;
|
|
|
|
// 如果有新日志,推送给所有客户端
|
|
if (!newLogs.empty()) {
|
|
Json::Value json;
|
|
json["type"] = "new_log";
|
|
json["content"] = Json::arrayValue;
|
|
|
|
// 只保留最新的100行
|
|
size_t start = newLogs.size() > 100 ? newLogs.size() - 100 : 0;
|
|
for (size_t i = start; i < newLogs.size(); ++i) {
|
|
json["content"].append(newLogs[i]);
|
|
}
|
|
|
|
Json::StreamWriterBuilder builder;
|
|
std::string msg = Json::writeString(builder, json);
|
|
|
|
std::lock_guard<std::mutex> lock(ws_connections_mutex_);
|
|
for (auto c : ws_connections_) {
|
|
if (c->send.len > MAX_WS_BACKLOG) {
|
|
continue;
|
|
}
|
|
mg_ws_send(c, msg.c_str(), msg.size(), WEBSOCKET_OP_TEXT);
|
|
}
|
|
}
|
|
}
|