From 659c470eba542383987aad227b7f918100f131fa Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期五, 11 九月 2026 15:09:05 +0800
Subject: [PATCH] 小智终端 5种 场景模式 OK
---
xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mqtt.c | 97 ++++++++++++++++++++++++++++++++++--------------
1 files changed, 68 insertions(+), 29 deletions(-)
diff --git a/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mqtt.c b/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mqtt.c
index 219255b..f0a4cb4 100644
--- a/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mqtt.c
+++ b/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mqtt.c
@@ -18,7 +18,7 @@
#include "app_task.h"
#define BOARD_MQTT_KEEPALIVE_SEC 120
-#define BOARD_MQTT_STATE_REPORT_INTERVAL_MS 5000
+#define BOARD_MQTT_STATE_REPORT_INTERVAL_MS 30000
#define BOARD_MQTT_RECONNECT_DELAY_MS 30000
#define BOARD_MQTT_NETWORK_TIMEOUT_MS 15000
#define BOARD_MQTT_FINAL_REPORT_WAIT_MS 10000
@@ -80,7 +80,6 @@
static void BoardMqtt_WaitConnectedForFinalReport(void);
static bool BoardMqtt_BeginTask(board_mqtt_task_type_t type);
static void BoardMqtt_FinishTask(board_mqtt_task_type_t type);
-static bool BoardMqtt_PlaybackSpeedIsSupported(float speed);
static void BoardMqtt_StopPlaylistTask(void);
static esp_err_t BoardMqtt_StartPlaylistTask(void);
@@ -145,6 +144,7 @@
int volume;
bool has_volume;
float speed;
+ int repeat;
int index;
int count;
} board_mqtt_playlist_item_t;
@@ -616,7 +616,8 @@
strcmp(action, "SET_CLOCK") == 0 || strcmp(action, "PLAY_MEDIA") == 0 ||
strcmp(action, "STOP_MEDIA") == 0 || strcmp(action, "DELETE_FILE") == 0 ||
strcmp(action, "SET_ALARM") == 0 || strcmp(action, "UNSET_ALARM") == 0 ||
- strcmp(action, "REBOOT") == 0;
+ strcmp(action, "REBOOT") == 0 || strcmp(action, "START_APP_TASK") == 0 ||
+ strcmp(action, "ENSURE_APP_DIRS") == 0;
}
static bool BoardMqtt_ActionIsTask(const char *action)
@@ -675,21 +676,6 @@
esp_err_t err = DS2312_Set_Unix_Time_Saved((time_t)ts->valuedouble);
return err == ESP_OK ? BoardMqtt_ResultOk("clock updated") :
BoardMqtt_ResultFail(BOARD_MQTT_ERR_EXEC_FAILED, esp_err_to_name(err));
-}
-
-static bool BoardMqtt_PlaybackSpeedIsSupported(float speed)
-{
- const float supported_speeds[] = {0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 2.0f};
- for (size_t i = 0; i < sizeof(supported_speeds) / sizeof(supported_speeds[0]); ++i) {
- float diff = speed - supported_speeds[i];
- if (diff < 0) {
- diff = -diff;
- }
- if (diff < 0.001f) {
- return true;
- }
- }
- return false;
}
static char *BoardMqtt_ReadPlaylistFile(void)
@@ -850,13 +836,22 @@
cJSON_Delete(root);
return ESP_ERR_INVALID_ARG;
}
- speed = (float)speed_json->valuedouble;
+ speed = SDCard_Clamp_MP3_Speed((float)speed_json->valuedouble);
}
- if (!BoardMqtt_PlaybackSpeedIsSupported(speed)) {
- cJSON_Delete(root);
- return ESP_ERR_INVALID_ARG;
+ int repeat = 1;
+ cJSON *repeat_json = cJSON_GetObjectItem(item, "repeat");
+ if (!repeat_json) {
+ repeat_json = cJSON_GetObjectItem(item, "count");
}
-
+ if (!repeat_json) {
+ repeat_json = cJSON_GetObjectItem(item, "play_count");
+ }
+ if (repeat_json) {
+ if (!BoardMqtt_NumberToInt(repeat_json, &repeat) || repeat < 1 || repeat > 99) {
+ cJSON_Delete(root);
+ return ESP_ERR_INVALID_ARG;
+ }
+ }
cJSON *stored_item = cJSON_CreateObject();
if (!stored_item) {
cJSON_Delete(root);
@@ -868,6 +863,7 @@
cJSON_AddNumberToObject(stored_item, "volume", volume_value);
}
cJSON_AddNumberToObject(stored_item, "speed", speed);
+ cJSON_AddNumberToObject(stored_item, "repeat", repeat);
cJSON_AddBoolToObject(stored_item, "completed", false);
cJSON_AddItemToArray(playlist_items, stored_item);
}
@@ -901,6 +897,7 @@
cJSON *sd_path = cJSON_GetObjectItem(item, "sd_path");
cJSON *volume = cJSON_GetObjectItem(item, "volume");
cJSON *speed_json = cJSON_GetObjectItem(item, "speed");
+ cJSON *repeat_json = cJSON_GetObjectItem(item, "repeat");
if (!cJSON_IsString(path) || !cJSON_IsString(sd_path)) {
cJSON_Delete(root);
return false;
@@ -925,10 +922,14 @@
}
next_item->has_volume = true;
}
- next_item->speed = cJSON_IsNumber(speed_json) ? (float)speed_json->valuedouble : 1.0f;
- if (!BoardMqtt_PlaybackSpeedIsSupported(next_item->speed)) {
- cJSON_Delete(root);
- return false;
+ next_item->speed = SDCard_Clamp_MP3_Speed(
+ cJSON_IsNumber(speed_json) ? (float)speed_json->valuedouble : 1.0f);
+ next_item->repeat = 1;
+ if (repeat_json) {
+ int repeat = 1;
+ if (BoardMqtt_NumberToInt(repeat_json, &repeat) && repeat >= 1) {
+ next_item->repeat = repeat > 99 ? 99 : repeat;
+ }
}
next_item->index = index;
next_item->count = count;
@@ -992,8 +993,10 @@
BoardMqtt_ShowPlaylistAlert(alert_message, "music");
SDCard_Show_Matching_JPG_For_MP3_Path(item.sd_path);
- ESP_LOGI(TAG, "playlist play item %d/%d: %s speed=%.2fx", item.index + 1, item.count, item.sd_path, item.speed);
- esp_err_t err = SDCard_Play_MP3_File_With_Speed(item.sd_path, item.speed);
+ ESP_LOGI(TAG, "playlist play item %d/%d: %s speed=%.2fx repeat=%d",
+ item.index + 1, item.count, item.sd_path, item.speed, item.repeat);
+ esp_err_t err = SDCard_Play_MP3_File_With_Speed_Repeat(
+ item.sd_path, item.speed, item.repeat > 0 ? item.repeat : 1, false);
if (err != ESP_OK) {
ESP_LOGE(TAG, "playlist item playback failed: %s", esp_err_to_name(err));
snprintf(alert_message, sizeof(alert_message), "鎾斁澶辫触 %d/%d: %s", item.index + 1, item.count, esp_err_to_name(err));
@@ -1894,6 +1897,38 @@
return BoardMqtt_ResultOk("app task started");
}
+static board_mqtt_action_result_t BoardMqtt_HandleEnsureAppDirs(cJSON *payload)
+{
+ if (!payload) {
+ return BoardMqtt_ResultFail(BOARD_MQTT_ERR_INVALID_PARAM, "missing payload");
+ }
+ cJSON *app_id = cJSON_GetObjectItem(payload, "app_id");
+ if (!cJSON_IsString(app_id) || !app_id->valuestring || app_id->valuestring[0] == '\0') {
+ return BoardMqtt_ResultFail(BOARD_MQTT_ERR_INVALID_PARAM, "missing app_id");
+ }
+ esp_err_t err = Board_EnsureAppLayout(app_id->valuestring, NULL);
+ if (err == ESP_ERR_INVALID_ARG || err == ESP_ERR_INVALID_SIZE) {
+ return BoardMqtt_ResultFail(BOARD_MQTT_ERR_INVALID_PARAM, "invalid app_id");
+ }
+ if (err != ESP_OK) {
+ return BoardMqtt_ResultFail(BOARD_MQTT_ERR_EXEC_FAILED, esp_err_to_name(err));
+ }
+ cJSON *tasks = cJSON_GetObjectItem(payload, "tasks");
+ if (cJSON_IsArray(tasks)) {
+ cJSON *task = NULL;
+ cJSON_ArrayForEach(task, tasks) {
+ if (!cJSON_IsString(task) || !task->valuestring) {
+ return BoardMqtt_ResultFail(BOARD_MQTT_ERR_INVALID_PARAM, "invalid tasks");
+ }
+ err = Board_EnsureAppLayout(app_id->valuestring, task->valuestring);
+ if (err != ESP_OK) {
+ return BoardMqtt_ResultFail(BOARD_MQTT_ERR_EXEC_FAILED, esp_err_to_name(err));
+ }
+ }
+ }
+ return BoardMqtt_ResultOk("app dirs ensured");
+}
+
static board_mqtt_action_result_t BoardMqtt_DispatchAction(const char *req_id, const char *action, cJSON *payload)
{
if (strcmp(action, "SET_VOLUME") == 0) return BoardMqtt_HandleSetVolume(payload);
@@ -1909,6 +1944,7 @@
if (strcmp(action, "DOWNLOAD") == 0) return BoardMqtt_HandleDownload(req_id, payload);
if (strcmp(action, "OTA_UPDATE") == 0) return BoardMqtt_HandleOtaUpdate(req_id, payload);
if (strcmp(action, "START_APP_TASK") == 0) return BoardMqtt_HandleStartAppTask(payload);
+ if (strcmp(action, "ENSURE_APP_DIRS") == 0) return BoardMqtt_HandleEnsureAppDirs(payload);
return BoardMqtt_ResultFail(BOARD_MQTT_ERR_UNSUPPORTED, "unsupported action");
}
@@ -2098,6 +2134,9 @@
(void)arg;
while (s_mqtt_client) {
vTaskDelay(pdMS_TO_TICKS(BOARD_MQTT_STATE_REPORT_INTERVAL_MS));
+ if (Board_Is_Audio_Busy()) {
+ continue;
+ }
BoardMqtt_PublishState();
}
s_state_task_handle = NULL;
--
Gitblit v1.9.1