From 0c18fe1db7579c54d52e90c0dc15d885f10879c2 Mon Sep 17 00:00:00 2001 From: Nanako <469449812@qq.com> Date: Wed, 10 Jul 2024 21:58:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 20 ++++++++++++++ cmake/retrieve_files.cmake | 55 ++++++++++++++++++++++++++++++++++++++ src/data_types.h | 20 +++++++++++--- src/main.cpp | 11 ++++++-- src/request_task.h | 20 +++++++++----- src/widget/login.h | 2 +- src/widget/main_page.h | 39 ++++++++++++++++++++------- 7 files changed, 146 insertions(+), 21 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 cmake/retrieve_files.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5af23e2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15) +project(inspur_bmc) +set(CMAKE_CXX_STANDARD 26) + +include(cmake/retrieve_files.cmake) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(RAPIDJSON REQUIRED rapidjson) +include_directories(${RAPIDJSON_INCLUDE_DIRS}) +link_directories(${RAPIDJSON_LIBRARY_DIRS}) + +add_subdirectory(third_party/imgui) +add_subdirectory(third_party/cpp-httplib) + +set(ALL_FILES "") +retrieve_files(${CMAKE_CURRENT_SOURCE_DIR}/src ALL_FILES) + +add_executable(${PROJECT_NAME} ${ALL_FILES}) +target_link_libraries(${PROJECT_NAME} imgui httplib) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/cmake/retrieve_files.cmake b/cmake/retrieve_files.cmake new file mode 100644 index 0000000..5dbe680 --- /dev/null +++ b/cmake/retrieve_files.cmake @@ -0,0 +1,55 @@ + +function(retrieve_files path out_files) + message(STATUS "Retrieving files in ${path}") + + # 递归查找文件夹下的 .h .hpp. ini 文件保存到 HEAD_FILES + file(GLOB_RECURSE HEAD_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS ${path}/*.h ${path}/*.hpp ${path}/*.ini) + + # 递归查找文件夹下的 *.cpp *.c 文件保存到 SRC_FILES + file(GLOB_RECURSE SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS ${path}/*.cpp ${path}*.c ${path}*.ixx) + + # 将 HEDADER_FILES 和 SRC_FILES 保存到 ALL_FILES 变量 + set(ALL_FILES ${HEAD_FILES} ${SRC_FILES}) + + set(RESULT "") + + # 对 ALL_FILES 变量里面的所有文件分类(保留资源管理器的目录结构) + foreach(fileItem ${ALL_FILES}) + # Get the directory of the source file + get_filename_component(PARENT_DIR "${fileItem}" DIRECTORY) + + # 用于检查平台的条件 + if(PARENT_DIR STREQUAL "windows") + if(WIN32) + set(RESULT "${RESULT};${fileItem}") + else() + continue() + endif() + elseif(PARENT_DIR STREQUAL "linux") + if(UNIX AND NOT APPLE) + set(RESULT "${RESULT};${fileItem}") + else() + continue() + endif() + elseif(PARENT_DIR STREQUAL "mac") + if(APPLE) + set(RESULT "${RESULT};${fileItem}") + else() + continue() + endif() + else() + # 如果文件夹名称不是平台,则始终包含 + set(RESULT "${RESULT};${fileItem}") + endif() + + # Remove common directory prefix to make the group + string(REPLACE "${path}" "" GROUP "${PARENT_DIR}") + # Make sure we are using windows slashes + string(REPLACE "/" "\\" GROUP "${GROUP}") + # Group into "Source Files" and "Header Files" + set(GROUP "${GROUP}") + source_group("${GROUP}" FILES "${fileItem}") + endforeach() + + set(${out_files} ${RESULT} PARENT_SCOPE) +endfunction() diff --git a/src/data_types.h b/src/data_types.h index 54945b6..fbdaa97 100644 --- a/src/data_types.h +++ b/src/data_types.h @@ -16,20 +16,34 @@ inline struct session_data { } } session; +enum class fan_status { + critical = 0, // 严重 + non_critical = 1, // 正常 + absent = 2, // 不可用 +}; + struct fan_info { int id; int present; - int status; + fan_status status; int speed_percent; int speed_rpm; static fan_info from_json(const rapidjson::Value& obj) { - return { + fan_info out{ .id = obj["Id"].GetInt(), .present = obj["Present"].GetInt(), - .status = obj["Status"].GetInt(), .speed_percent = obj["SpeedPercent"].GetInt(), .speed_rpm = obj["SpeedRPM"].GetInt() }; + const int s = obj["Status"].GetInt(); + if (s == 2) { + out.status = fan_status::absent; + } else if (out.speed_rpm == 0) { + out.status = fan_status::critical; + } else { + out.status = fan_status::non_critical; + } + return out; } }; diff --git a/src/main.cpp b/src/main.cpp index 5c23f11..8ff0fab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,8 @@ #include "widget/login.h" #include "widget/main_page.h" +bool is_login = false; + std::string get_window_title() { return "Inspur BMC"; } @@ -12,6 +14,8 @@ void configure_imgui(ImGuiIO& io) { io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleFonts; + io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleViewports; io.ConfigViewportsNoAutoMerge = true; } @@ -23,11 +27,14 @@ void tick_imgui(float delta_time) { // 执行imgui绘制(在tick_imgui之后执行) void draw_imgui(float delta_time) { ImGui::DockSpaceOverViewport(); - draw_login(); - draw_page(); + if (is_login) + draw_page(); + else + draw_login(); } int main(int argc, char *argv[]) { run_imgui(); + task_executor::sync_run_task(); return 0; } diff --git a/src/request_task.h b/src/request_task.h index 17527cb..6245d8b 100644 --- a/src/request_task.h +++ b/src/request_task.h @@ -28,12 +28,12 @@ public: return process(); }); } + virtual T process() = 0; [[nodiscard]] const char* api() const { return api_; } protected: - virtual T process() = 0; const char* api_; }; @@ -47,6 +47,12 @@ public: task_instance.setup(std::forward(args)...); return task_instance.async_process(); } + template + static auto sync_run_task(Args&&... args) { + static T task_instance; + task_instance.setup(std::forward(args)...); + return task_instance.process(); + } }; template @@ -59,12 +65,12 @@ public: params_ = params; } -protected: T process() override { T result; post_request(task::api(), params_, result); return result; } +protected: httplib::Params params_; }; @@ -79,7 +85,6 @@ public: explicit get_task(const char* api) : task(api) { } -protected: T process() override { T result; get_request(task::api(), result); @@ -87,6 +92,11 @@ protected: } }; +template<> +inline void get_task::process() { + get_request(api()); +} + class login_task : public post_task { public: login_task() : post_task("WEBSES/create") {} @@ -98,7 +108,6 @@ public: params.emplace("WEBVAR_PASSWORD", encode_content(password)); set_params(params); } -protected: session_data process() override { delete cli; headers.clear(); @@ -126,10 +135,9 @@ public: params.emplace("PERCENT", std::to_string(speed_percent)); set_params(params); } -private: - }; SIMPLE_GET_TASK(get_fan_info_task, "getfaninfo", std::vector) SIMPLE_GET_TASK(get_running_time_task, "getrunningtime", running_time) SIMPLE_GET_TASK(get_psu_info_task, "getallpsuinfo", std::vector) +SIMPLE_GET_TASK(logout_task, "WEBSES/logout", void) diff --git a/src/widget/login.h b/src/widget/login.h index f578fa3..07aace7 100644 --- a/src/widget/login.h +++ b/src/widget/login.h @@ -6,7 +6,7 @@ #include "request_task.h" #define BUF_SIZE 256 -inline bool is_login = false; +extern bool is_login; inline char ip_buf[BUF_SIZE] { "192.168.1.10" }; inline char username_buf[BUF_SIZE] { "admin" }; inline char password_buf[BUF_SIZE] { "admin" }; diff --git a/src/widget/main_page.h b/src/widget/main_page.h index 4d56362..e3520eb 100644 --- a/src/widget/main_page.h +++ b/src/widget/main_page.h @@ -31,18 +31,39 @@ inline void draw_running_time() { ImGui::Text("Server running time: %d days %d hours", running_time_.days, running_time_.hours); } +inline ImU32 get_fan_status_color(fan_status status) { + switch (status) { + case fan_status::absent: + return IM_COL32(255, 0, 0, 255); + case fan_status::critical: + return IM_COL32(255, 255, 0, 255); + case fan_status::non_critical: + return IM_COL32(0, 255, 0, 255); + default: + return IM_COL32(255, 255, 255, 255); + } +} + inline void draw_fan_infos() { for (auto& fan_info : fan_infos_) { - fan_info.status; - - ImGui::Text("Fan %d: %d RPM", fan_info.id, fan_info.speed_rpm); - std::string label = "Speed##" + std::to_string(fan_info.id); - ImGui::InputInt(label.c_str(), &fan_info.speed_percent, 1, 100); - if (ImGui::IsItemDeactivatedAfterEdit()) { - // 更新风扇转速 - fan_info.speed_percent = std::clamp(fan_info.speed_percent, 0, 100); - auto future = task_executor::run_task(fan_info.id, fan_info.speed_percent); + // 根据风扇状态绘制不同的颜色 和 启用/禁用输入框 + ImGui::PushStyleColor(ImGuiCol_Text, get_fan_status_color(fan_info.status)); + { + ImGui::BeginDisabled(fan_info.status != fan_status::non_critical); + { + ImGui::Text("Fan %d: %d RPM", fan_info.id, fan_info.speed_rpm); + std::string label = "Speed##" + std::to_string(fan_info.id); + ImGui::SliderInt(label.c_str(), &fan_info.speed_percent, 0, 100); + if (ImGui::IsItemDeactivatedAfterEdit()) { + // 更新风扇转速 + fan_info.speed_percent = std::clamp(fan_info.speed_percent, 0, 100); + task_executor::run_task(fan_info.id, fan_info.speed_percent); + } + } + ImGui::EndDisabled(); } + + ImGui::PopStyleColor(); } }