Files
ignis-core/app/core/scheduler.py
Artem Kokos b6b25fa2a1 BBFbyOpus
2026-04-01 22:51:24 +07:00

64 lines
2.2 KiB
Python

import os
import logging
import pytz
from datetime import datetime, timedelta
from dotenv import load_dotenv
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.triggers.cron import CronTrigger
from sqlalchemy import delete
from app.core.database import sync_engine, async_session
from app.models.event_log import EventLog
from app.drivers.wiz import WizDriver
load_dotenv()
logger = logging.getLogger(__name__)
TZ_NAME = os.getenv("APP_TIMEZONE", "Asia/Novosibirsk")
app_tz = pytz.timezone(TZ_NAME)
RETENTION_DAYS = int(os.getenv("EVENT_LOG_RETENTION_DAYS", "30"))
jobstores = {"default": SQLAlchemyJobStore(engine=sync_engine)}
scheduler = AsyncIOScheduler(jobstores=jobstores, timezone=app_tz)
async def execute_lamp_command(ip: str, params: dict):
"""
Универсальное выполнение команды.
params может содержать: state, dimming, temp, sceneId, r, g, b
"""
driver = WizDriver()
await driver.set_pilot(ip, params)
logger.info(f"Сработало расписание для {ip}: {params}")
async def cleanup_old_events():
"""Удаляет записи event_log старше RETENTION_DAYS."""
cutoff = (datetime.now() - timedelta(days=RETENTION_DAYS)).isoformat()
async with async_session() as session:
result = await session.execute(
delete(EventLog).where(EventLog.timestamp < cutoff)
)
await session.commit()
if result.rowcount:
logger.info(
f"Очистка лога: удалено {result.rowcount} записей старше {RETENTION_DAYS} дней"
)
async def start_scheduler():
if not scheduler.running:
scheduler.start()
# Очистка лога -- раз в сутки в 03:00
scheduler.add_job(
cleanup_old_events,
CronTrigger(hour=3, minute=0, timezone=app_tz),
id="cleanup_event_log",
name="Очистка старых событий",
replace_existing=True,
)
logger.info(f"Планировщик запущен. Таймзона: {TZ_NAME}")