- Cache the latest fetched tomorrow weather and expose it via /api/system/weather/latest - Add a header Clock widget showing date/time plus the cached weather summary - Redirect useless-talk mentions from the weather bot to the useless-tips webhook - Switch Bedrock auth from bearer token to standard IAM access key/secret Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
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()
|