"""One-shot collection/backfill and monthly report orchestration.""" from datetime import UTC, datetime, timedelta from pathlib import Path from .config import PowerMeterConfig from .gateway import PowerMeterGateway from .repository import PostgresPowerMeterRepository from .report import write_pdf class PowerMeterCollector: def __init__(self, config: PowerMeterConfig, gateway: PowerMeterGateway, repository: PostgresPowerMeterRepository) -> None: self.config, self.gateway, self.repository = config, gateway, repository def backfill(self, start: datetime, end: datetime) -> int: readings = self.gateway.read(self.config, start, end) for reading in readings: self.repository.write(self.config.name, reading) return len(readings) def poll_once(self, now: datetime | None = None) -> int: now = now or datetime.now(UTC) start = now - timedelta(seconds=self.config.poll_interval_seconds * 2) return self.backfill(start, now) def monthly_report(config: PowerMeterConfig, repository: PostgresPowerMeterRepository, month: str) -> Path: start = datetime.fromisoformat(month + "-01").replace(tzinfo=UTC) end = datetime.fromisoformat(month + "-01").replace(tzinfo=UTC) if start.month == 12: end = end.replace(year=start.year + 1, month=1) else: end = end.replace(month=start.month + 1) summary = repository.monthly(config.name, start, end, month) output = Path(config.report_mount_path) / config.name / month[:4] / f"{config.name}_Powermeter_{month}.pdf" write_pdf(summary, output) repository.save_report_metadata(summary, str(output)) return output