- Add CPU/GPU memory monitoring endpoint and frontend widget - Add Amazon Bedrock model support (API key / inference profiles) plus model selector entries - Add Discord weather/laundry notification job (JMA forecast + LLM-generated message) - Add Discord bot that replies to mentions via the configured LLM, with weather-aware context - Add scheduled "useless tips" job with separate webhook and quiet-hours skip - Switch FastAPI startup to lifespan handler, log viewer, markdown rendering, and toast UI additions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
from fastapi import APIRouter
|
|
import psutil
|
|
from pydantic import BaseModel
|
|
|
|
from app.core.scheduler import send_useless_tip, send_weather_laundry_notification
|
|
|
|
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"}
|