chore: migrate project into clean repository

This commit is contained in:
yuuux
2026-08-13 16:50:52 +08:00
commit d1d25a09e7
27405 changed files with 9422808 additions and 0 deletions

View File

@@ -0,0 +1,186 @@
/**
* @file ota_view.c
* @brief OTA status view implementation
*/
#define TAG "ota_view"
#include "ota_view.h"
#include "lisa_ui.h"
#include "lisa_ui_llm_base.h"
#include "lisa_ui_fonts.h"
#include <stdio.h>
typedef struct {
lisa_ui_llm_base_t base;
lv_obj_t *status_label;
lv_obj_t *progress_label;
lv_obj_t *eta_label;
char status_text[48];
char progress_text[32];
char eta_text[32];
} lisa_ui_ota_view_t;
static void ota_view_constructor(const lv_obj_class_t *class_p, lv_obj_t *obj);
static void ota_view_destructor(const lv_obj_class_t *class_p, lv_obj_t *obj);
const lv_obj_class_t lisa_ui_ota_view_class = {
.base_class = &lisa_ui_llm_base_class,
.instance_size = sizeof(lisa_ui_ota_view_t),
.constructor_cb = ota_view_constructor,
.destructor_cb = ota_view_destructor,
};
static void ota_view_constructor(const lv_obj_class_t *class_p, lv_obj_t *obj)
{
LV_UNUSED(class_p);
lisa_ui_ota_view_t *view = (lisa_ui_ota_view_t *)obj;
lv_obj_t *bar = lisa_ui_llm_base_bar_get(obj);
if (bar) {
lv_obj_add_flag(bar, LV_OBJ_FLAG_HIDDEN);
}
lv_obj_t *container = lisa_ui_llm_base_container_get(obj);
if (!container) {
return;
}
view->status_label = lv_label_create(container);
lv_label_set_text(view->status_label, "正在检查更新…");
lv_obj_set_style_text_color(view->status_label, lv_color_white(), 0);
lv_obj_set_style_text_font(view->status_label, &lv_font_chinese_16, 0);
lv_obj_set_width(view->status_label, lv_pct(100));
lv_obj_set_style_text_align(view->status_label, LV_TEXT_ALIGN_CENTER, 0);
lv_obj_align(view->status_label, LV_ALIGN_CENTER, 0, -16);
view->progress_label = lv_label_create(container);
lv_label_set_text(view->progress_label, "");
lv_obj_set_style_text_color(view->progress_label, lv_color_white(), 0);
lv_obj_set_style_text_font(view->progress_label, &lv_font_chinese_16, 0);
lv_obj_set_style_text_opa(view->progress_label, LV_OPA_70, 0);
lv_obj_set_width(view->progress_label, lv_pct(100));
lv_obj_set_style_text_align(view->progress_label, LV_TEXT_ALIGN_CENTER, 0);
lv_obj_align(view->progress_label, LV_ALIGN_CENTER, 0, 8);
view->eta_label = lv_label_create(container);
lv_label_set_text(view->eta_label, "");
lv_obj_set_style_text_color(view->eta_label, lv_color_white(), 0);
lv_obj_set_style_text_font(view->eta_label, &lv_font_chinese_16, 0);
lv_obj_set_style_text_opa(view->eta_label, LV_OPA_50, 0);
lv_obj_set_width(view->eta_label, lv_pct(100));
lv_obj_set_style_text_align(view->eta_label, LV_TEXT_ALIGN_CENTER, 0);
lv_obj_align(view->eta_label, LV_ALIGN_BOTTOM_MID, 0, -12);
}
static void ota_view_destructor(const lv_obj_class_t *class_p, lv_obj_t *obj)
{
(void)class_p;
(void)obj;
}
lv_obj_t *lisa_ui_ota_view_create(lv_obj_t *parent)
{
lv_obj_t *obj = lv_obj_class_create_obj(&lisa_ui_ota_view_class, parent);
lv_obj_class_init_obj(obj);
return obj;
}
static const char *ota_target_name(ota_target_e target)
{
switch (target) {
case OTA_TARGET_WAKE_WORD:
return "唤醒词";
case OTA_TARGET_PROMPT_TONE:
return "提示音";
case OTA_TARGET_EMOJI:
return "表情";
default:
return "资源";
}
}
static void ota_view_format_size(char *buf, size_t buf_size, uint32_t bytes)
{
if (bytes >= 1024 * 1024) {
snprintf(buf, buf_size, "%.1fMB", (float)bytes / (1024.0f * 1024.0f));
} else {
snprintf(buf, buf_size, "%uKB", bytes / 1024);
}
}
void lisa_ui_ota_view_update(lv_obj_t *obj, const ota_state_t *state)
{
if (!obj || !lv_obj_has_class(obj, &lisa_ui_ota_view_class)) {
return;
}
lisa_ui_ota_view_t *view = (lisa_ui_ota_view_t *)obj;
switch (state->state) {
case OTA_STATE_UPDATING: {
// 第一行N/M 正在更新XXX…
if (state->update_total > 0) {
snprintf(view->status_text, sizeof(view->status_text), "%u/%u 正在更新%s…",
state->update_index, state->update_total, ota_target_name(state->target));
} else {
snprintf(view->status_text, sizeof(view->status_text), "正在更新%s…",
ota_target_name(state->target));
}
lv_label_set_text_static(view->status_label, view->status_text);
// 第二行:已下载 / 总大小
if (state->bytes_total > 0) {
char processed_str[16], total_str[16];
ota_view_format_size(processed_str, sizeof(processed_str), state->bytes_processed);
ota_view_format_size(total_str, sizeof(total_str), state->bytes_total);
snprintf(view->progress_text, sizeof(view->progress_text), "%s / %s", processed_str, total_str);
lv_label_set_text_static(view->progress_label, view->progress_text);
} else {
lv_label_set_text_static(view->progress_label, "");
}
// 第三行:预计剩余时间
if (state->bytes_processed < state->bytes_total) {
if (state->bytes_processed > 0 && state->elapsed_ms > 0) {
uint32_t remaining_bytes = state->bytes_total - state->bytes_processed;
float speed = (float)state->bytes_processed / (float)state->elapsed_ms;
uint32_t eta_sec = (uint32_t)((float)remaining_bytes / speed / 1000.0f);
uint32_t eta_min = (eta_sec + 59) / 60;
if (eta_min <= 1) {
snprintf(view->eta_text, sizeof(view->eta_text), "预计不到1分钟");
} else {
snprintf(view->eta_text, sizeof(view->eta_text), "预计%u分钟", eta_min);
}
} else {
snprintf(view->eta_text, sizeof(view->eta_text), "预计约1分钟");
}
lv_label_set_text_static(view->eta_label, view->eta_text);
} else {
lv_label_set_text_static(view->eta_label, "");
}
break;
}
case OTA_STATE_SUCCESSED:
lv_label_set_text_static(view->status_label, "更新完毕");
lv_label_set_text_static(view->progress_label, "");
if (state->reboot == OTA_REBOOT_STRATEGY_AUTO) {
lv_label_set_text_static(view->eta_label, "正在重启…");
} else {
lv_label_set_text_static(view->eta_label, "请手动重启设备");
}
break;
case OTA_STATE_FAILED:
lv_label_set_text_static(view->status_label, "更新失败");
lv_label_set_text_static(view->progress_label, "");
if (state->reboot == OTA_REBOOT_STRATEGY_AUTO) {
lv_label_set_text_static(view->eta_label, "正在重启…");
} else {
lv_label_set_text_static(view->eta_label, "请手动重启设备");
}
break;
default:
break;
}
}