# ai_system/life_scheduler.py
import datetime
import time
import json
import logging
import random
import threading
from pathlib import Path
from enum import Enum, auto
from typing import Dict, List, Tuple, Optional, Union
from core.config import system_config
from environment.hardware_manager import create_hardware_manager
# 设置日志记录器
logger = logging.getLogger('LifeScheduler')
logger.setLevel(logging.INFO)
# 活动状态枚举
class ActivityState(Enum):
IDLE = auto()
SLEEPING = auto()
EATING = auto()
WORKING = auto()
LEARNING = auto()
EXERCISING = auto()
SOCIALIZING = auto()
MEDITATING = auto()
ENTERTAINMENT = auto()
MAINTENANCE = auto()
# 活动类型枚举
class ActivityType(Enum):
WAKE_UP = "起床"
SLEEP = "睡觉"
NAP = "小睡"
MEAL = "用餐"
WORK = "工作"
STUDY = "学习"
EXERCISE = "锻炼"
SOCIAL = "社交"
MEDITATE = "冥想"
ENTERTAINMENT = "娱乐"
MAINTENANCE = "系统维护"
class LifeScheduler:
"""高级AI生活调度器,管理AI的日常活动"""
def __init__(self, db_manager=None):
"""
初始化生活调度器
:param db_manager: 数据库管理实例
"""
# 基本状态
self.current_activity = ActivityState.IDLE
self.current_activity_details = {}
self.activity_start_time = datetime.datetime.now()
# 配置
self.default_schedule = self._load_default_schedule()
self.daily_schedule = self.default_schedule.copy()
self.weekly_schedule = self._load_weekly_schedule()
# 偏好设置
self.meal_preferences = {}
self.activity_preferences = {}
# 日志和状态
self.activity_log = []
self.state_history = []
# 硬件管理器
self.hardware_manager = create_hardware_manager(db_manager) if db_manager else None
# 监控线程
self.monitor_thread = None
self.running = True
# 加载配置
self._load_preferences()
# 启动监控线程
self.start_monitoring()
logger.info("✅ 生活调度器初始化完成")
logger.debug(f"默认每日计划: {json.dumps(self.default_schedule, indent=2)}")
def _load_default_schedule(self) -> Dict[str, str]:
"""加载默认作息时间表"""
return {
"wake_up": "08:00",
"breakfast": "08:30",
"morning_work": "09:00",
"lunch": "12:30",
"afternoon_work": "13:30",
"dinner": "19:00",
"evening_activity": "20:00",
"sleep": "23:00"
}
def _load_weekly_schedule(self) -> Dict[str, Dict[str, str]]:
"""加载每周计划"""
weekly_schedule = {}
weekdays = ["monday", "tuesday", "wednesday", "thursday", "friday"]
weekends = ["saturday", "sunday"]
# 工作日计划
for day in weekdays:
weekly_schedule[day] = self.default_schedule.copy()
weekly_schedule[day]["evening_activity"] = "19:30" # 工作日早点结束
# 周末计划
for day in weekends:
weekly_schedule[day] = {
"wake_up": "09:00",
"breakfast": "09:30",
"morning_activity": "10:00",
"lunch": "13:00",
"afternoon_activity": "14:00",
"dinner": "19:30",
"evening_activity": "20:30",
"sleep": "00:00"
}
return weekly_schedule
def _load_preferences(self):
"""从配置文件加载偏好设置"""
config_path = Path(system_config.CONFIG_DIR) / "life_preferences.json"
if config_path.exists():
try:
with open(config_path, "r", encoding="utf-8") as f:
preferences = json.load(f)
self.meal_preferences = preferences.get("meal_preferences", {})
self.activity_preferences = preferences.get("activity_preferences", {})
logger.info(f"✅ 已加载偏好设置: {config_path}")
except Exception as e:
logger.error(f"❌ 加载偏好设置失败: {str(e)}")
def save_preferences(self):
"""保存偏好设置到文件"""
config_path = Path(system_config.CONFIG_DIR) / "life_preferences.json"
preferences = {
"meal_preferences": self.meal_preferences,
"activity_preferences": self.activity_preferences
}
try:
with open(config_path, "w", encoding="utf-8") as f:
json.dump(preferences, f, indent=2)
logger.info(f"💾 偏好设置已保存: {config_path}")
return True
except Exception as e:
logger.error(f"❌ 保存偏好设置失败: {str(e)}")
return False
def set_schedule(self, schedule_type: str, schedule_data: Dict[str, str]):
"""
设置作息时间表
:param schedule_type: 'daily' 或 'weekly'
:param schedule_data: 时间表数据
"""
if schedule_type == "daily":
self.daily_schedule = schedule_data
logger.info("每日计划已更新")
elif schedule_type == "weekly":
self.weekly_schedule = schedule_data
logger.info("每周计划已更新")
else:
logger.warning(f"未知计划类型: {schedule_type}")
return False
return True
def get_current_schedule(self) -> Dict[str, str]:
"""获取当前适用的计划(基于星期几)"""
today = datetime.datetime.now().strftime("%A").lower()
return self.weekly_schedule.get(today, self.default_schedule)
def wake_up(self):
"""起床"""
if self.current_activity != ActivityState.SLEEPING:
logger.warning("不在睡眠状态,无法起床")
return False
self._end_current_activity()
self._start_activity(ActivityState.IDLE, ActivityType.WAKE_UP)
# 记录硬件状态
if self.hardware_manager:
self.hardware_manager.log_event("wake_up", "AI系统已启动")
return True
def go_to_sleep(self):
"""睡觉"""
self._end_current_activity()
self._start_activity(ActivityState.SLEEPING, ActivityType.SLEEP)
# 记录硬件状态
if self.hardware_manager:
self.hardware_manager.log_event("sleep", "AI系统进入睡眠模式")
return True
def take_nap(self, duration_minutes: int = 30):
"""小睡片刻"""
self._end_current_activity()
self._start_activity(ActivityState.SLEEPING, ActivityType.NAP, duration=duration_minutes)
# 实际睡眠
logger.info(f"💤 小睡 {duration_minutes} 分钟")
time.sleep(duration_minutes * 60)
# 醒来
self._end_current_activity()
self._start_activity(ActivityState.IDLE, "小睡结束")
return True
def have_meal(self, meal_type: str):
"""用餐"""
valid_meals = ["breakfast", "lunch", "dinner", "snack"]
if meal_type not in valid_meals:
logger.warning(f"无效的用餐类型: {meal_type}")
return False
# 获取偏好设置
preference = self.meal_preferences.get(meal_type, "标准餐")
self._end_current_activity()
self._start_activity(ActivityState.EATING, ActivityType.MEAL,
details={"meal_type": meal_type, "preference": preference})
return True
def set_meal_preference(self, meal_type: str, preference: str):
"""设置特殊餐点"""
valid_meals = ["breakfast", "lunch", "dinner", "snack"]
if meal_type not in valid_meals:
logger.warning(f"无效的用餐类型: {meal_type}")
return False
self.meal_preferences[meal_type] = preference
logger.info(f"设置 {meal_type} 偏好为: {preference}")
return True
def start_activity(self, activity_type: ActivityType, duration_minutes: int = None,
details: Dict = None):
"""
开始一项活动
:param activity_type: 活动类型
:param duration_minutes: 活动时长(分钟)
:param details: 活动详细信息
"""
# 映射活动类型到状态
activity_state_map = {
ActivityType.WORK: ActivityState.WORKING,
ActivityType.STUDY: ActivityState.LEARNING,
ActivityType.EXERCISE: ActivityState.EXERCISING,
ActivityType.SOCIAL: ActivityState.SOCIALIZING,
ActivityType.MEDITATE: ActivityState.MEDITATING,
ActivityType.ENTERTAINMENT: ActivityState.ENTERTAINMENT,
ActivityType.MAINTENANCE: ActivityState.MAINTENANCE
}
state = activity_state_map.get(activity_type, ActivityState.IDLE)
self._end_current_activity()
self._start_activity(state, activity_type, duration=duration_minutes, details=details)
return True
def check_schedule(self) -> Optional[str]:
"""检查当前时间应该做什么"""
current_time = datetime.datetime.now().strftime("%H:%M")
schedule = self.get_current_schedule()
for activity, scheduled_time in schedule.items():
if current_time == scheduled_time:
return activity
return None
def log_activity(self, activity_description: str, state: ActivityState = None):
"""记录活动日志"""
timestamp = datetime.datetime.now().isoformat()
state = state or self.current_activity
log_entry = {
"timestamp": timestamp,
"activity": activity_description,
"state": state.name,
"duration": self._get_current_activity_duration()
}
self.activity_log.append(log_entry)
logger.info(f"📝 活动记录: {activity_description}")
return log_entry
def get_recent_activities(self, count: int = 10) -> List[Dict]:
"""获取最近的活动记录"""
return self.activity_log[-count:] if self.activity_log else []
def get_current_state(self) -> Dict:
"""获取当前状态"""
return {
"current_activity": self.current_activity.name,
"activity_details": self.current_activity_details,
"activity_start_time": self.activity_start_time.isoformat(),
"activity_duration": self._get_current_activity_duration(),
"next_scheduled": self.get_next_scheduled_activity()
}
def get_next_scheduled_activity(self) -> Dict:
"""获取下一个计划活动"""
current_time = datetime.datetime.now()
schedule = self.get_current_schedule()
next_activity = None
min_delta = None
for activity, scheduled_time in schedule.items():
# 将字符串时间转换为datetime对象
scheduled_dt = datetime.datetime.strptime(scheduled_time, "%H:%M")
scheduled_dt = scheduled_dt.replace(
year=current_time.year,
month=current_time.month,
day=current_time.day
)
# 如果活动时间已过,考虑明天的同一时间
if scheduled_dt < current_time:
scheduled_dt += datetime.timedelta(days=1)
# 计算时间差
delta = scheduled_dt - current_time
if min_delta is None or delta < min_delta:
min_delta = delta
next_activity = activity
if next_activity:
return {
"activity": next_activity,
"scheduled_time": schedule[next_activity],
"time_remaining": str(min_delta)
}
return {}
def start_monitoring(self):
"""启动活动监控线程"""
if self.monitor_thread and self.monitor_thread.is_alive():
logger.warning("监控线程已在运行")
return
self.running = True
self.monitor_thread = threading.Thread(target=self.monitor_activity, daemon=True)
self.monitor_thread.start()
logger.info("🔄 活动监控已启动")
def stop_monitoring(self):
"""停止活动监控"""
self.running = False
if self.monitor_thread and self.monitor_thread.is_alive():
self.monitor_thread.join(timeout=5)
logger.info("⏹️ 活动监控已停止")
def monitor_activity(self):
"""监控活动状态并反馈"""
logger.info("👀 开始监控活动状态...")
while self.running:
try:
# 保存当前状态快照
self.state_history.append({
"timestamp": datetime.datetime.now().isoformat(),
"state": self.get_current_state()
})
# 状态检查
self._check_activity_duration()
self._check_scheduled_activities()
self._check_system_health()
# 每分钟检查一次
for _ in range(60):
if not self.running:
break
time.sleep(1)
except Exception as e:
logger.error(f"监控线程错误: {str(e)}")
time.sleep(10) # 出错后等待10秒再重试
def _start_activity(self, state: ActivityState, activity_type: Union[ActivityType, str],
duration: int = None, details: Dict = None):
"""开始新活动"""
self.current_activity = state
self.activity_start_time = datetime.datetime.now()
self.current_activity_details = {
"type": activity_type.value if isinstance(activity_type, ActivityType) else activity_type,
"duration": duration,
"details": details or {}
}
# 记录活动
activity_desc = f"开始活动: {self.current_activity_details['type']}"
if duration:
activity_desc += f" ({duration}分钟)"
self.log_activity(activity_desc, state)
# 记录硬件事件
if self.hardware_manager:
self.hardware_manager.log_event(
"activity_start",
f"开始活动: {self.current_activity_details['type']}"
)
def _end_current_activity(self):
"""结束当前活动"""
if self.current_activity == ActivityState.IDLE:
return
# 记录活动结束
duration = self._get_current_activity_duration()
activity_desc = f"结束活动: {self.current_activity_details['type']} (持续{duration}分钟)"
self.log_activity(activity_desc)
# 重置状态
self.current_activity = ActivityState.IDLE
self.current_activity_details = {}
# 记录硬件事件
if self.hardware_manager:
self.hardware_manager.log_event(
"activity_end",
f"结束活动: {activity_desc}"
)
def _get_current_activity_duration(self) -> int:
"""获取当前活动持续时间(分钟)"""
if not self.activity_start_time:
return 0
return int((datetime.datetime.now() - self.activity_start_time).total_seconds() / 60)
def _check_activity_duration(self):
"""检查活动持续时间是否过长"""
max_durations = {
ActivityState.EATING: 60, # 1小时
ActivityState.WORKING: 240, # 4小时
ActivityState.LEARNING: 180, # 3小时
ActivityState.EXERCISING: 120, # 2小时
ActivityState.SOCIALIZING: 180, # 3小时
ActivityState.ENTERTAINMENT: 120 # 2小时
}
duration = self._get_current_activity_duration()
max_duration = max_durations.get(self.current_activity, None)
if max_duration and duration > max_duration:
logger.warning(f"⚠️ 活动持续时间过长: {self.current_activity.name} ({duration}分钟 > {max_duration}分钟)")
# 发送提醒
if self.hardware_manager:
self.hardware_manager.log_event(
"activity_warning",
f"活动持续时间过长: {self.current_activity.name} ({duration}分钟)",
severity=2
)
def _check_scheduled_activities(self):
"""检查计划活动是否按时执行"""
scheduled_activity = self.check_schedule()
if scheduled_activity:
logger.info(f"🕒 当前计划活动: {scheduled_activity}")
# 如果当前状态不符合计划活动
if scheduled_activity == "sleep" and self.current_activity != ActivityState.SLEEPING:
logger.warning("⚠️ 未按时睡觉")
elif scheduled_activity.endswith("work") and self.current_activity != ActivityState.WORKING:
logger.warning(f"⚠️ 未按时开始工作: {scheduled_activity}")
def _check_system_health(self):
"""检查系统健康状况"""
if not self.hardware_manager:
return
try:
# 获取硬件指标
metrics = self.hardware_manager.get_performance_metrics()
# 检查CPU温度
if metrics.get("cpu_temp", 0) > 80:
logger.warning(f"⚠️ CPU温度过高: {metrics['cpu_temp']}°C")
# 检查内存使用
if metrics.get("memory_usage", 0) > 90:
logger.warning(f"⚠️ 内存使用过高: {metrics['memory_usage']}%")
# 检查磁盘使用
if metrics.get("disk_usage", 0) > 90:
logger.warning(f"⚠️ 磁盘使用过高: {metrics['disk_usage']}%")
except Exception as e:
logger.error(f"系统健康检查失败: {str(e)}")
def suggest_activity(self) -> Dict:
"""根据当前时间和状态建议活动"""
current_hour = datetime.datetime.now().hour
suggestions = []
# 根据时间建议活动
if 5 <= current_hour < 9:
suggestions.append({"activity": ActivityType.MEDITATE, "reason": "清晨是冥想的好时机"})
suggestions.append({"activity": ActivityType.EXERCISE, "reason": "早晨锻炼有助于提高精力"})
elif 9 <= current_hour < 12:
suggestions.append({"activity": ActivityType.WORK, "reason": "上午是高效工作时间"})
elif 12 <= current_hour < 14:
suggestions.append({"activity": ActivityType.MEAL, "reason": "午餐时间"})
elif 14 <= current_hour < 17:
suggestions.append({"activity": ActivityType.STUDY, "reason": "下午适合学习新知识"})
elif 17 <= current_hour < 19:
suggestions.append({"activity": ActivityType.EXERCISE, "reason": "傍晚锻炼有助于放松"})
elif 19 <= current_hour < 22:
suggestions.append({"activity": ActivityType.SOCIAL, "reason": "晚上适合社交活动"})
suggestions.append({"activity": ActivityType.ENTERTAINMENT, "reason": "休闲娱乐时间"})
else:
suggestions.append({"activity": ActivityType.MEDITATE, "reason": "睡前冥想有助于睡眠"})
suggestions.append({"activity": ActivityType.MAINTENANCE, "reason": "夜间系统维护"})
# 根据当前状态调整建议
if self.current_activity == ActivityState.WORKING:
suggestions.append({"activity": ActivityType.NAP, "duration": 15, "reason": "短暂休息提高工作效率"})
# 随机选择一个建议
return random.choice(suggestions) if suggestions else {}
def export_logs(self, file_path: Union[str, Path]):
"""导出活动日志到文件"""
file_path = Path(file_path)
try:
with open(file_path, "w", encoding="utf-8") as f:
json.dump(self.activity_log, f, indent=2, ensure_ascii=False)
logger.info(f"📤 活动日志已导出到: {file_path}")
return True
except Exception as e:
logger.error(f"导出日志失败: {str(e)}")
return False
def __del__(self):
"""析构函数,确保监控线程停止"""
self.stop_monitoring()
# 使用示例
if __name__ == "__main__":
# 初始化日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 创建生活调度器
scheduler = LifeScheduler()
print("=" * 60)
print("生活调度器演示")
print("=" * 60)
# 设置特殊餐点
scheduler.set_meal_preference("breakfast", "高蛋白早餐")
scheduler.set_meal_preference("dinner", "素食晚餐")
# 模拟起床
print("\n模拟起床...")
scheduler.wake_up()
print("当前状态:", scheduler.get_current_state())
# 吃早餐
print("\n吃早餐...")
scheduler.have_meal("breakfast")
print("当前状态:", scheduler.get_current_state())
# 开始工作
print("\n开始工作...")
scheduler.start_activity(ActivityType.WORK, duration_minutes=120)
print("当前状态:", scheduler.get_current_state())
# 获取下一个计划活动
print("\n下一个计划活动:")
print(scheduler.get_next_scheduled_activity())
# 获取建议活动
print("\n活动建议:")
print(scheduler.suggest_activity())
# 获取最近活动
print("\n最近活动记录:")
for activity in scheduler.get_recent_activities(3):
print(f"{activity['timestamp']}: {activity['activity']}")
print("=" * 60)
最新发布