refactor(schedule): 优化休眠状态判断逻辑

将原先仅检查日程表首尾项的休眠判断方式,重构为通过关键词匹配所有日程项。
这样可以更灵活地在一天中的任何时段安排休眠,而不仅限于一天的开始或结束。

- 引入 `sleep_keywords` 列表,用于识别表示休眠的活动。
- 遍历当天的所有日程,检查活动名称是否包含休眠关键词。
- 如果关键词匹配,则进一步检查当前时间是否处于该活动的时间范围内。
- 保留了对唤醒状态的检查,确保在被唤醒时不会错误地判断为休眠。

同时,对 `hfc_context.py` 中的 `last_read_time` 初始值进行了微调,以改善相关逻辑的初始行为。
This commit is contained in:
minecraft1024a
2025-08-22 12:17:10 +08:00
parent 5498e21835
commit 67bb7de8aa
2 changed files with 41 additions and 37 deletions

View File

@@ -42,7 +42,7 @@ class HfcContext:
self.energy_value = 5.0
self.last_message_time = time.time()
self.last_read_time = time.time() - 1
self.last_read_time = time.time() - 10
self.action_manager = ActionManager()

View File

@@ -314,60 +314,64 @@ class ScheduleManager:
def is_sleeping(self, wakeup_manager=None) -> bool:
"""
检查当前是否处于休眠时间(日程表的第一项或最后一项)
通过关键词匹配检查当前是否处于休眠时间
Args:
wakeup_manager: 可选的唤醒度管理器,用于检查是否被唤醒
wakeup_manager: 可选的唤醒度管理器,用于检查是否被唤醒
Returns:
bool: 是否处于休眠状态
bool: 是否处于休眠状态
"""
if not global_config.schedule.enable_is_sleep:
return False
if not self.today_schedule:
return False
now = datetime.now().time()
# 从配置获取关键词,如果配置中没有则使用默认列表
sleep_keywords = ["休眠", "睡觉", "梦乡",]
# 修复:应该获取列表的第一个元素
first_item = self.today_schedule[0]
last_item = self.today_schedule[-1]
now = datetime.now().time()
is_in_sleep_time = False
for item in [first_item, last_item]:
# 遍历当天的所有日程
for event in self.today_schedule:
try:
time_range = item.get("time_range")
if not time_range:
activity = event.get("activity", "").strip()
time_range = event.get("time_range")
if not activity or not time_range:
continue
start_str, end_str = time_range.split('-')
start_time = datetime.strptime(start_str.strip(), "%H:%M").time()
end_time = datetime.strptime(end_str.strip(), "%H:%M").time()
# 1. 检查活动内容是否包含任一休眠关键词
if any(keyword in activity for keyword in sleep_keywords):
# 2. 如果包含,再检查当前时间是否在该时间段内
start_str, end_str = time_range.split('-')
start_time = datetime.strptime(start_str.strip(), "%H:%M").time()
end_time = datetime.strptime(end_str.strip(), "%H:%M").time()
is_in_time_range = False
if start_time <= end_time: # 同一天
if start_time <= now < end_time:
is_in_time_range = True
else: # 跨天
if now >= start_time or now < end_time:
is_in_time_range = True
# 如果时间匹配,则进入最终判断
if is_in_time_range:
# 检查是否被唤醒
if wakeup_manager and wakeup_manager.is_in_angry_state():
logger.info(f"在休眠活动 '{activity}' 期间,但已被唤醒。")
return False
logger.info(f"当前处于休眠活动 '{activity}' 中。")
return True # 找到匹配的休眠活动直接返回True
if start_time <= end_time:
# 同一天内的时间段
if start_time <= now < end_time:
is_in_sleep_time = True
break
else:
# 跨天的时间段
if now >= start_time or now < end_time:
is_in_sleep_time = True
break
except (ValueError, KeyError, AttributeError) as e:
logger.warning(f"解析休眠日程事件失败: {item}, 错误: {e}")
logger.warning(f"解析日程事件时出错: {event}, 错误: {e}")
continue
# 如果不在休眠时间直接返回False
if not is_in_sleep_time:
return False
# 如果在休眠时间,检查是否被唤醒度管理器唤醒
if wakeup_manager and wakeup_manager.is_in_angry_state():
logger.debug("虽然在休眠时间,但已被唤醒度管理器唤醒")
return False
return True
# 遍历完所有日程都未找到匹配的休眠活动
return False
def _validate_schedule_with_pydantic(self, schedule_data) -> bool:
"""使用Pydantic验证日程数据格式和完整性"""