init
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
"""Супервизор: владеет набором RecorderTask по всем включённым камерам."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ..config import Camera, Config
|
||||
from ..models import CameraStatus
|
||||
from ..services import go2rtc
|
||||
from .recorder_task import RecorderTask
|
||||
|
||||
log = logging.getLogger("nvr.supervisor")
|
||||
|
||||
|
||||
class Supervisor:
|
||||
def __init__(self, config: Config, on_status=None):
|
||||
self.config = config
|
||||
self.on_status = on_status
|
||||
self.tasks: dict[str, RecorderTask] = {}
|
||||
|
||||
def _input_url(self, cam: Camera) -> str:
|
||||
# запись основного потока идёт через рестрим go2rtc (одна сессия к камере)
|
||||
return go2rtc.restream_main_url(self.config, cam.id)
|
||||
|
||||
def start_all(self) -> None:
|
||||
for cam in self.config.cameras:
|
||||
task = RecorderTask(cam, self.config.storage, on_status=self.on_status,
|
||||
input_url=self._input_url(cam))
|
||||
self.tasks[cam.id] = task
|
||||
if cam.enabled:
|
||||
task.start()
|
||||
log.info("recorder started: %s", cam.id)
|
||||
else:
|
||||
log.info("recorder skipped (disabled): %s", cam.id)
|
||||
|
||||
async def stop_all(self) -> None:
|
||||
for task in self.tasks.values():
|
||||
await task.stop()
|
||||
|
||||
def statuses(self) -> list[CameraStatus]:
|
||||
return [t.status for t in self.tasks.values()]
|
||||
|
||||
def status(self, cam_id: str) -> CameraStatus | None:
|
||||
task = self.tasks.get(cam_id)
|
||||
return task.status if task else None
|
||||
|
||||
def log_tail(self, cam_id: str) -> list[str]:
|
||||
task = self.tasks.get(cam_id)
|
||||
return task.log_tail if task else []
|
||||
|
||||
async def restart(self, cam_id: str) -> bool:
|
||||
task = self.tasks.get(cam_id)
|
||||
if not task:
|
||||
return False
|
||||
await task.stop()
|
||||
task.start()
|
||||
return True
|
||||
|
||||
def add_camera(self, cam: Camera) -> None:
|
||||
"""Создаёт задачу записи для новой камеры и запускает (если включена)."""
|
||||
task = RecorderTask(cam, self.config.storage, on_status=self.on_status,
|
||||
input_url=self._input_url(cam))
|
||||
self.tasks[cam.id] = task
|
||||
if cam.enabled:
|
||||
task.start()
|
||||
log.info("recorder added: %s", cam.id)
|
||||
|
||||
async def remove_camera(self, cam_id: str) -> None:
|
||||
task = self.tasks.pop(cam_id, None)
|
||||
if task:
|
||||
await task.stop()
|
||||
log.info("recorder removed: %s", cam_id)
|
||||
|
||||
async def replace_camera(self, cam: Camera) -> None:
|
||||
await self.remove_camera(cam.id)
|
||||
self.add_camera(cam)
|
||||
|
||||
async def restart_all(self) -> None:
|
||||
"""Пересоздаёт все задачи (например, после смены настроек хранилища)."""
|
||||
for cam in list(self.config.cameras):
|
||||
await self.replace_camera(cam)
|
||||
Reference in New Issue
Block a user