From 220e4fab27b7f419b3e89e2f2d28ae789aac09d7 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期四, 08 十月 2026 16:29:55 +0800
Subject: [PATCH] 5种场景模式家长端ok
---
xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/system.c | 144 +++++++++++++++++++++++++++++++++--------------
1 files changed, 101 insertions(+), 43 deletions(-)
diff --git a/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/system.c b/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/system.c
index d1c2a1f..c892541 100644
--- a/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/system.c
+++ b/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/system.c
@@ -1,6 +1,7 @@
#include "system.h"
#include "config.h"
#include "app_task.h"
+#include "parent_schedule.h"
#include "display/lvgl_display/jpg/jpeg_to_image.h"
#include <esp_heap_caps.h>
@@ -71,6 +72,8 @@
static bool battery_charging_gpio_initialized;
static alarm_entry_t current_alarm1_entry;
static bool current_alarm1_valid;
+static alarm_entry_t schedule_wake_entry;
+static bool schedule_wake_valid;
static TaskHandle_t alarm_monitor_task_handle;
static TaskHandle_t alarm_power_off_restore_task_handle;
@@ -89,6 +92,8 @@
static bool get_current_time(i2c_dev_t *i2c_dev, struct tm *timeinfo);
static int select_next_alarm_index(const alarm_store_t *store, const struct tm *now);
static int alarm_delta_seconds(const alarm_entry_t *entry, const struct tm *now);
+static const alarm_entry_t *select_soonest_alarm(const alarm_store_t *store, const struct tm *now);
+static void program_soonest_alarm(i2c_dev_t *i2c_dev, const struct tm *now);
static int mqtt_weekday_to_tm_wday(int day);
static uint8_t tm_wday_to_repeat_bit(int tm_wday);
static bool alarm_entry_equals(const alarm_entry_t *left, const alarm_entry_t *right);
@@ -159,10 +164,13 @@
if (!command || command[0] == '\0') {
return false;
}
+ if (Board_Is_Chat_Return_Command(command)) {
+ return false;
+ }
return strcmp(command, OFFLINE_REPEATER_WORD) == 0 ||
strcmp(command, OFFLINE_START_REPEATER_WORD) == 0 ||
- strstr(command, OFFLINE_REPEATER_WORD) ||
- strstr(command, OFFLINE_START_REPEATER_WORD);
+ strstr(command, OFFLINE_START_REPEATER_WORD) ||
+ strstr(command, "鎵撳紑娉涘惉");
}
bool Board_Handle_Offline_Command(const char *command)
@@ -198,20 +206,52 @@
esp_sntp_init();
}
-void DS2312_Update_Alarm(i2c_dev_t *i2c_dev, struct tm *time)
+static const alarm_entry_t *select_soonest_alarm(const alarm_store_t *store, const struct tm *now)
+{
+ const alarm_entry_t *best = NULL;
+ int best_delta = SECONDS_PER_DAY * 8 + 1;
+ if (store && store->count > 0) {
+ int index = select_next_alarm_index(store, now);
+ if (index >= 0) {
+ best = &store->entries[index];
+ best_delta = alarm_delta_seconds(best, now);
+ }
+ }
+ if (schedule_wake_valid) {
+ int delta = alarm_delta_seconds(&schedule_wake_entry, now);
+ if (delta < best_delta) {
+ best = &schedule_wake_entry;
+ }
+ }
+ return best;
+}
+
+static void program_soonest_alarm(i2c_dev_t *i2c_dev, const struct tm *now)
{
alarm_store_t store;
if (load_alarm_store(&store) != ESP_OK) {
- disable_alarm1(i2c_dev);
+ memset(&store, 0, sizeof(store));
+ }
+ const alarm_entry_t *best = select_soonest_alarm(&store, now);
+ if (!best) {
+ if (current_alarm1_valid && !Board_Is_Power_Off()) {
+ disable_alarm1(i2c_dev);
+ }
return;
}
-
- if (store.count == 0) {
- disable_alarm1(i2c_dev);
- ESP_LOGI(TAG, "alarm list is empty");
+ if (!current_alarm1_valid) {
+ program_alarm1(i2c_dev, best);
return;
}
+ int next_delta = alarm_delta_seconds(best, now);
+ int current_delta = alarm_delta_seconds(¤t_alarm1_entry, now);
+ if (next_delta < current_delta || !alarm_entry_equals(best, ¤t_alarm1_entry)) {
+ program_alarm1(i2c_dev, best);
+ }
+}
+void DS2312_Update_Alarm(i2c_dev_t *i2c_dev, struct tm *time)
+{
struct tm now;
if (time) {
now = *time;
@@ -219,14 +259,7 @@
ESP_LOGW(TAG, "current time unavailable, skip alarm update");
return;
}
-
- int index = select_next_alarm_index(&store, &now);
- if (index < 0) {
- disable_alarm1(i2c_dev);
- return;
- }
-
- program_alarm1(i2c_dev, &store.entries[index]);
+ program_soonest_alarm(i2c_dev, &now);
}
void DS2312_Start_Alarm_Monitor(i2c_dev_t *i2c_dev)
@@ -241,6 +274,43 @@
alarm_monitor_task_handle = NULL;
ESP_LOGE(TAG, "create alarm monitor task failed");
}
+}
+
+bool Board_Get_Wall_Clock(struct tm *out)
+{
+ if (!out) {
+ return false;
+ }
+ return get_current_time(ds2321_dev, out);
+}
+
+esp_err_t DS2312_Set_Schedule_Wake(int hour, int min, int sec, uint8_t weekday_bit)
+{
+ if (hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || sec > 59 ||
+ (weekday_bit & ALARM_REPEAT_ALL) == 0) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ memset(&schedule_wake_entry, 0, sizeof(schedule_wake_entry));
+ strlcpy(schedule_wake_entry.id, "_sched", sizeof(schedule_wake_entry.id));
+ schedule_wake_entry.hour = (uint8_t)hour;
+ schedule_wake_entry.min = (uint8_t)min;
+ schedule_wake_entry.sec = (uint8_t)sec;
+ schedule_wake_entry.flags = ALARM_ENTRY_ENABLED;
+ schedule_wake_entry.repeat_mask = (uint8_t)(weekday_bit & ALARM_REPEAT_ALL);
+ schedule_wake_valid = true;
+ DS2312_Update_Alarm(ds2321_dev, NULL);
+ ESP_LOGI(TAG, "schedule wake %02d:%02d:%02d mask=0x%02x", hour, min, sec, schedule_wake_entry.repeat_mask);
+ return ESP_OK;
+}
+
+void DS2312_Clear_Schedule_Wake(void)
+{
+ if (!schedule_wake_valid) {
+ return;
+ }
+ schedule_wake_valid = false;
+ memset(&schedule_wake_entry, 0, sizeof(schedule_wake_entry));
+ DS2312_Update_Alarm(ds2321_dev, NULL);
}
void DS2312_Add_Alarm_Time(i2c_dev_t *i2c_dev, int hour, int min, int sec)
@@ -1623,14 +1693,6 @@
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
- alarm_store_t store;
- if (load_alarm_store(&store) != ESP_OK || store.count == 0) {
- if (current_alarm1_valid) {
- disable_alarm1(i2c_dev);
- }
- continue;
- }
-
struct tm now;
if (!get_current_time(i2c_dev, &now)) {
continue;
@@ -1641,28 +1703,24 @@
ESP_LOGI(TAG, "DS3231 alarm1 triggered");
ds3231_clear_alarm_flags(i2c_dev, DS3231_ALARM_1);
current_alarm1_valid = false;
- schedule_power_off_restore_from_alarm();
- }
-
- int next_index = select_next_alarm_index(&store, &now);
- if (next_index < 0) {
- if (current_alarm1_valid && !Board_Is_Power_Off()) {
- disable_alarm1(i2c_dev);
+ if (Board_Schedule_ClaimDue()) {
+ if (Board_Is_Power_Off()) {
+ schedule_power_off_restore_from_alarm();
+ } else {
+ Board_Schedule_OnAlarmFired();
+ }
}
- continue;
+ } else if (Board_Schedule_ClaimDue()) {
+ ESP_LOGI(TAG, "schedule wall clock due");
+ if (Board_Is_Power_Off()) {
+ schedule_power_off_restore_from_alarm();
+ } else {
+ Board_Schedule_OnAlarmFired();
+ }
}
- alarm_entry_t *next_alarm = &store.entries[next_index];
- if (!current_alarm1_valid) {
- program_alarm1(i2c_dev, next_alarm);
- continue;
- }
-
- int next_delta = alarm_delta_seconds(next_alarm, &now);
- int current_delta = alarm_delta_seconds(¤t_alarm1_entry, &now);
- if (next_delta < current_delta || !alarm_entry_equals(next_alarm, ¤t_alarm1_entry)) {
- program_alarm1(i2c_dev, next_alarm);
- }
+ Board_Schedule_OnLessonFilesUpdated();
+ program_soonest_alarm(i2c_dev, &now);
}
}
--
Gitblit v1.9.1