from datetime import datetime, timedelta from typing import Optional from fastapi import APIRouter, Depends, HTTPException from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.date import DateTrigger from app.core.state import state_manager from app.core.scheduler import scheduler, execute_lamp_command from app.drivers.wiz import WizDriver from app.api.deps import verify_token router = APIRouter(dependencies=[Depends(verify_token)]) wiz = WizDriver() @router.post("/at") async def add_task_at_time( target_id: str, run_at: datetime, is_group: bool = False, state: Optional[bool] = None, brightness: Optional[int] = None, scene: Optional[str] = None, ): params = {} if state is not None: params["state"] = state if brightness is not None: params["dimming"] = brightness if scene and scene in wiz.SCENES: params["sceneId"] = wiz.SCENES[scene] ips = state_manager.get_group_ips(target_id) if is_group else [] if not is_group: dev = state_manager.devices.get(target_id) if dev: ips = [dev.ip] if not ips: raise HTTPException(status_code=404, detail="Цель не найдена") job_ids = [] for ip in ips: job = scheduler.add_job( execute_lamp_command, DateTrigger(run_date=run_at, timezone=scheduler.timezone), args=[ip, params], name=f"{'Group' if is_group else 'Device'}: {target_id} | {params}", ) job_ids.append(job.id) return {"status": "scheduled", "jobs": job_ids, "run_at": run_at} @router.post("/cron") async def add_cron_task( target_id: str, hour: str, minute: str, day_of_week: str = "*", is_group: bool = True, state: bool = True, ): ips = state_manager.get_group_ips(target_id) if is_group else [] if not is_group: dev = state_manager.devices.get(target_id) if dev: ips = [dev.ip] if not ips: raise HTTPException(status_code=404, detail="Цель не найдена") trigger = CronTrigger( hour=hour, minute=minute, day_of_week=day_of_week, timezone=scheduler.timezone ) job_ids = [] for ip in ips: job = scheduler.add_job( execute_lamp_command, trigger, args=[ip, {"state": state}], name=f"CRON: {target_id} | {hour}:{minute}", ) job_ids.append(job.id) return {"status": "cron_scheduled", "jobs": job_ids} @router.get("/tasks") async def get_all_tasks(): jobs = [] for job in scheduler.get_jobs(): jobs.append( { "id": job.id, "name": job.name, "next_run": ( job.next_run_time.isoformat() if job.next_run_time else None ), "params": str(job.args[1]) if len(job.args) > 1 else None, } ) return {"tasks": jobs} @router.delete("/{job_id}") async def cancel_task(job_id: str): try: scheduler.remove_job(job_id) return {"status": "deleted"} except: raise HTTPException(status_code=404, detail="Задача не найдена")