kunlang_video/include/app_config.hpp

161 lines
4.9 KiB
C++
Raw Normal View History

2025-09-08 14:55:07 +08:00
// app_config.hpp
#pragma once
#include <string>
#include <map>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <unistd.h>
#include <limits.h>
#include <stdexcept>
#include "logger.hpp"
using json = nlohmann::json;
using ordered_json = nlohmann::ordered_json;
// ------------------- 摄像头结构体 -------------------
struct Camera
{
std::string device;
std::string name;
int width, height, fps;
bool enabled;
};
// ------------------- MQTT Topic -------------------
struct VehicleMQTTTopics
{
std::string heartbeat_up;
std::string video_down;
std::string video_down_ack;
std::string substream_down;
std::string substream_down_ack;
std::string reset_down;
std::string reset_down_ack;
void fill_with_veh_id(const std::string &vehId)
{
heartbeat_up = "adcpcmcc/v1/vehmedia/" + vehId + "/heartbeat/up";
video_down = "adcpcmcc/v1/vehmedia/" + vehId + "/video/down";
video_down_ack = "adcpcmcc/v1/vehmedia/" + vehId + "/video/down/ack";
substream_down = "adcpcmcc/v1/vehmedia/" + vehId + "/substream/down";
substream_down_ack = "adcpcmcc/v1/vehmedia/" + vehId + "/substream/down/ack";
reset_down = "adcpcmcc/v1/vehmedia/" + vehId + "/reset/down";
reset_down_ack = "adcpcmcc/v1/vehmedia/" + vehId + "/reset/down/ack";
}
};
// ------------------- MQTT 配置 -------------------
struct MQTTConfig
{
std::string vehicle_id;
std::string server_ip;
int server_port;
bool need_username_pwd;
std::string client_id;
std::string username;
std::string password;
int keep_alive;
VehicleMQTTTopics topics;
};
// ------------------- 总配置 -------------------
struct AppConfig
{
std::vector<Camera> cameras;
MQTTConfig mqtt;
static AppConfig load_from_file(const std::string &filepath)
{
AppConfig cfg;
std::ifstream ifs(filepath);
if (!ifs.is_open())
{
LOG_ERROR("[Config] Failed to open config file: " + filepath);
throw std::runtime_error("Failed to open config file: " + filepath);
}
json j;
ifs >> j;
// 读取摄像头
if (j.contains("cameras"))
{
for (auto &c : j["cameras"])
{
Camera cam;
cam.device = c.value("device", "");
cam.name = c.value("name", "");
cam.width = c.value("width", 1280);
cam.height = c.value("height", 720);
cam.fps = c.value("fps", 30);
cam.enabled = c.value("enabled", false);
cfg.cameras.push_back(cam);
LOG_INFO("[Config] Loaded camera: " + cam.name +
" (" + cam.device + "), enabled=" + std::to_string(cam.enabled));
}
}
// 读取 MQTT
if (!j.contains("mqtt_server"))
{
LOG_ERROR("[Config] Missing 'mqtt_server' section");
throw std::runtime_error("Config file missing 'mqtt_server'");
}
auto &m = j["mqtt_server"];
cfg.mqtt.vehicle_id = std::to_string(m.value("veh_id", 0));
cfg.mqtt.server_ip = m.value("address", "");
cfg.mqtt.server_port = m.value("port", 1883);
cfg.mqtt.need_username_pwd = m.value("need_username_pwd", true);
cfg.mqtt.client_id = m.value("client_id", "");
cfg.mqtt.username = m.value("username", "");
cfg.mqtt.password = m.value("password", "");
cfg.mqtt.keep_alive = m.value("mqtt_heart_threshold", 2000);
cfg.mqtt.topics.fill_with_veh_id(cfg.mqtt.vehicle_id);
LOG_INFO("[Config] Loaded MQTT server: " + cfg.mqtt.server_ip +
":" + std::to_string(cfg.mqtt.server_port));
LOG_INFO("[Config] MQTT client ID: " + cfg.mqtt.client_id);
LOG_INFO("[Config] MQTT Topics: " + cfg.mqtt.topics.heartbeat_up + ", " +
cfg.mqtt.topics.video_down + ", " + cfg.mqtt.topics.video_down_ack);
return cfg;
}
};
// ------------------- 辅助函数 -------------------
inline std::string get_executable_dir()
{
char result[PATH_MAX] = {0};
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
if (count == -1)
{
LOG_ERROR("[Config] Failed to read /proc/self/exe");
throw std::runtime_error("Failed to read /proc/self/exe");
}
std::string full_path(result, count);
auto pos = full_path.find_last_of('/');
if (pos == std::string::npos)
{
LOG_ERROR("[Config] Failed to find executable directory");
throw std::runtime_error("Failed to find executable directory");
}
return full_path.substr(0, pos);
}
inline std::string get_executable_dir_file_path(const std::string &filename)
{
std::string dir = get_executable_dir();
if (dir.back() != '/')
dir += '/';
return dir + filename;
}
// 全局配置变量
extern AppConfig g_app_config;