feat(ui): add weather and lucky color commands

This commit is contained in:
chenjintao
2026-08-18 14:59:07 +08:00
parent e0dbcdd273
commit 96f5e535d3
6 changed files with 454 additions and 2 deletions
@@ -147,6 +147,8 @@ bool control_plane_extract_model_command(const char *text,
cJSON *direction = cJSON_GetObjectItemCaseSensitive(cmd_json, "转向");
cJSON *calibrate = cJSON_GetObjectItemCaseSensitive(cmd_json, "校准");
cJSON *chouqian = cJSON_GetObjectItemCaseSensitive(cmd_json, "抽签");
cJSON *weather = cJSON_GetObjectItemCaseSensitive(cmd_json, "天气");
cJSON *lucky_color = cJSON_GetObjectItemCaseSensitive(cmd_json, "喜色");
if (cJSON_IsString(direction) && direction->valuestring != NULL) {
if (is_supported_model_direction(direction->valuestring)) {
@@ -173,6 +175,16 @@ bool control_plane_extract_model_command(const char *text,
}
found = true;
}
} else if (cJSON_IsString(weather) && weather->valuestring != NULL &&
weather->valuestring[0] != '\0') {
*out_command_type = CONTROL_PLANE_MODEL_COMMAND_WEATHER;
strlcpy(out_value, weather->valuestring, out_value_capacity);
found = true;
} else if (cJSON_IsString(lucky_color) && lucky_color->valuestring != NULL &&
lucky_color->valuestring[0] != '\0') {
*out_command_type = CONTROL_PLANE_MODEL_COMMAND_LUCKY_COLOR;
strlcpy(out_value, lucky_color->valuestring, out_value_capacity);
found = true;
}
cJSON_Delete(cmd_json);
@@ -1040,6 +1040,57 @@ static esp_err_t control_plane_run_model_calibration_motion(void)
return control_plane_rotate_to_angle(start_angle);
}
typedef struct {
const char *color_name;
domain_wuxing_element_t element;
} control_plane_lucky_color_mapping_t;
/*
* Lucky-color names are intentionally mapped in one place so product changes
* can replace colors without touching model-command parsing or LCD playback.
*/
static const control_plane_lucky_color_mapping_t s_lucky_color_mappings[] = {
{"金", DOMAIN_WUXING_ELEMENT_METAL},
{"棕", DOMAIN_WUXING_ELEMENT_WOOD},
{"蓝", DOMAIN_WUXING_ELEMENT_WATER},
{"红", DOMAIN_WUXING_ELEMENT_FIRE},
{"黄", DOMAIN_WUXING_ELEMENT_EARTH},
};
static bool control_plane_resolve_lucky_color(const char *color_name,
domain_wuxing_element_t *out_element)
{
if (color_name == NULL || out_element == NULL) {
return false;
}
for (size_t i = 0;
i < sizeof(s_lucky_color_mappings) / sizeof(s_lucky_color_mappings[0]);
++i) {
if (strcmp(color_name, s_lucky_color_mappings[i].color_name) == 0) {
*out_element = s_lucky_color_mappings[i].element;
return true;
}
}
return false;
}
static esp_err_t control_plane_show_lucky_color_expression(const char *color_name)
{
domain_wuxing_element_t element = DOMAIN_WUXING_ELEMENT_WATER;
if (!control_plane_resolve_lucky_color(color_name, &element)) {
return ESP_ERR_NOT_FOUND;
}
const domain_expression_request_t request = {
.id = DOMAIN_EXPRESSION_WUXING,
.trigger = DOMAIN_EXPRESSION_TRIGGER_MODEL_LUCKY_COLOR,
.wuxing_element = element,
.wuxing_element_valid = true,
};
return domain_runtime_request_expression(&request);
}
static esp_err_t control_plane_show_chouqian_expression(size_t result_index, bool result_index_valid)
{
const domain_expression_request_t request = {
@@ -1107,6 +1158,22 @@ static void control_plane_model_command_task(void *arg)
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
ESP_LOGW(TAG, "Chouqian expression failed: %s", esp_err_to_name(err));
}
} else if (cmd.command_type == CONTROL_PLANE_MODEL_COMMAND_WEATHER) {
/*
* TODO: Request the weather LCD expression here after its assets
* and domain expression mapping are available. Parsing and
* dispatch stay active now to preserve the model-command contract.
*/
ESP_LOGI(TAG, "Weather UI pending, received model command: %s", cmd.value);
} else if (cmd.command_type == CONTROL_PLANE_MODEL_COMMAND_LUCKY_COLOR) {
ESP_LOGI(TAG, "Lucky color triggered by model command: %s", cmd.value);
esp_err_t err = control_plane_show_lucky_color_expression(cmd.value);
if (err != ESP_OK) {
ESP_LOGW(TAG,
"Show lucky-color expression failed for '%s': %s",
cmd.value,
esp_err_to_name(err));
}
}
}