Files
xInfo/main/App.cpp
T
2026-08-31 15:05:13 +08:00

118 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file App.cpp
* @brief xInfo 环境监控终端主应用逻辑。
*/
#include "App.h"
#include "esp_log.h"
#include "esp_netif_sntp.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <ctime>
// ============ 编译期常量(来自 Kconfig / menuconfig)============
static constexpr uint32_t kDisplayIntervalMs = CONFIG_DISPLAY_REFRESH_INTERVAL_MIN * 60 * 1000; // 墨水屏刷新间隔
static const char *TAG = "App";
App::App()
: wifi_(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD),
dht11Driver_(GPIO_NUM_5),
dashFetcher_(sensorDriver_, dht11Driver_) {}
App::~App() {}
void App::init() {
ESP_LOGI(TAG, "正在初始化 xInfo 环境监控终端...");
// 步骤 1:连接 WiFi
wifi_.connect();
// 步骤 2:SNTP 时间同步(获取网络时间用于显示准确时钟)
ESP_LOGI(TAG, "正在同步 NTP 时间(服务器: %s)...", CONFIG_NTP_SERVER);
setenv("TZ", "CST-8", 1);
tzset();
esp_sntp_config_t sntpConfig = ESP_NETIF_SNTP_DEFAULT_CONFIG(CONFIG_NTP_SERVER);
esp_netif_sntp_init(&sntpConfig);
constexpr int kMaxRetries = 3;
for (int i = 0; i < kMaxRetries; ++i) {
esp_err_t ret = esp_netif_sntp_sync_wait(pdMS_TO_TICKS(CONFIG_NTP_SYNC_TIMEOUT_SEC * 1000));
if (ret == ESP_OK) {
time_t now = time(nullptr);
struct tm timeinfo;
localtime_r(&now, &timeinfo);
char timeBuf[64];
strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", &timeinfo);
ESP_LOGI(TAG, "NTP 时间同步成功: %s", timeBuf);
break;
}
ESP_LOGW(TAG, "NTP 同步第 %d 次超时...", i + 1);
}
// 步骤 3:初始化墨水屏硬件
display_.initHardware();
// 步骤 4:初始化空气质量传感器驱动
sensorDriver_.init();
// 步骤 5:初始化 DHT11 温湿度传感器驱动
dht11Driver_.init();
}
void App::run() {
ESP_LOGI(TAG, "进入主循环...");
std::string mac = wifi_.getMac();
while (true) {
ESP_LOGI(TAG, "采集本地环境数据并刷新墨水屏...");
auto dashData = dashFetcher_.fetch();
if (dashData && dashData != lastDashData_) {
display_.beginDrawing();
// 绘制环境与网络监控界面
std::string ssid = wifi_.getSsid();
display_.drawTopBanner(ssid.empty() || ssid == "N/A" ? "Offline" : ssid);
display_.drawThermoHygrometer(*dashData); // 核心温湿度看板与舒适度
display_.drawAirQuality(*dashData); // 空气质量多维度指标(CO2/TVOC/甲醛)
display_.drawBottomInfoBar(wifi_.getIp(), mac); // 底部 IP 与 MAC 网络参数
// 定期全刷消除墨水屏残影
int maxFastRefreshes = 180 / CONFIG_DISPLAY_REFRESH_INTERVAL_MIN;
if (maxFastRefreshes < 1) maxFastRefreshes = 1;
#ifdef CONFIG_DISPLAY_BWR
std::string redContent = ssid;
bool needFullRefresh = lastRedContent_.empty()
|| (redContent != lastRedContent_)
|| (fullRefreshCounter_ >= maxFastRefreshes);
#else
bool needFullRefresh = (fullRefreshCounter_ == 0)
|| (fullRefreshCounter_ >= maxFastRefreshes);
#endif
if (needFullRefresh) {
display_.updateFullAndSleep();
#ifdef CONFIG_DISPLAY_BWR
lastRedContent_ = redContent;
#endif
fullRefreshCounter_ = 0;
} else {
display_.updateFastAndSleep();
fullRefreshCounter_++;
}
lastDashData_ = dashData;
ESP_LOGI(TAG, "墨水屏刷新完成(%s)", needFullRefresh ? "全量" : "快刷");
} else {
ESP_LOGI(TAG, "数据无变化,跳过本次墨水屏刷新");
}
// 休眠等待下一个刷新周期
vTaskDelay(pdMS_TO_TICKS(kDisplayIntervalMs));
}
}