from fastapi import APIRouter import psutil from pydantic import BaseModel from app.core.scheduler import send_useless_tip, send_weather_laundry_notification from app.core.weather_cache import get_latest as get_latest_weather router = APIRouter(prefix="/api/system", tags=["system"]) class MemoryStats(BaseModel): cpu_percent: float memory_percent: float memory_used_mb: float memory_total_mb: float gpu_memory_used_mb: float | None = None gpu_memory_total_mb: float | None = None gpu_memory_percent: float | None = None @router.get("/memory", response_model=MemoryStats) async def get_memory_stats(): """CPU と GPU のメモリ使用状況を返す""" # CPU/メモリ情報 cpu_percent = psutil.cpu_percent(interval=0.1) memory = psutil.virtual_memory() stats = { "cpu_percent": cpu_percent, "memory_percent": memory.percent, "memory_used_mb": memory.used / (1024 * 1024), "memory_total_mb": memory.total / (1024 * 1024), } # GPU 情報(オプション) try: import pynvml pynvml.nvmlInit() device_count = pynvml.nvmlDeviceGetCount() if device_count > 0: handle = pynvml.nvmlDeviceGetHandleByIndex(0) mem_info = pynvml.nvmlDeviceGetMemoryInfo(handle) stats["gpu_memory_used_mb"] = mem_info.used / (1024 * 1024) stats["gpu_memory_total_mb"] = mem_info.total / (1024 * 1024) stats["gpu_memory_percent"] = (mem_info.used / mem_info.total) * 100 pynvml.nvmlShutdown() except Exception: pass return MemoryStats(**stats) @router.post("/weather-notify/test") async def test_weather_notify(): """天気予報→Discord通知を手動で即時実行する(動作確認用)""" await send_weather_laundry_notification() return {"status": "sent"} @router.post("/useless-tip/test") async def test_useless_tip(): """どうでもいいtips→Discord通知を手動で即時実行する(動作確認用)""" await send_useless_tip() return {"status": "sent"} @router.get("/weather/latest") async def get_latest_weather_data(): """直近で取得した明日の天気データを返す(未取得ならnull)""" return get_latest_weather()