#!/usr/bin/env python3 """Entry point and orchestrator for enabled home-control functions.""" from __future__ import annotations import argparse import logging import signal from pathlib import Path import yaml from lib import _arrival_detection def load_config(path: Path) -> dict: with path.open(encoding="utf-8") as stream: config = yaml.safe_load(stream) if not isinstance(config, dict): raise ValueError("configuration must be a YAML mapping") return config def run(config: dict, once: bool = False) -> int: stopped = False def stop(*_: object) -> None: nonlocal stopped stopped = True signal.signal(signal.SIGTERM, stop) signal.signal(signal.SIGINT, stop) arrival_config = config.get("arrival_detection") if not isinstance(arrival_config, dict): raise ValueError("arrival_detection configuration is required") if not arrival_config.get("enabled", True): logging.getLogger("home_control").info("arrival detection is disabled") return 0 return _arrival_detection.run(arrival_config, lambda: stopped, once=once) def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--config", type=Path, default=Path(__file__).with_name("service.yaml")) parser.add_argument("--once", action="store_true", help="check once and print connected/absent") args = parser.parse_args() config = load_config(args.config) arrival = config.get("arrival_detection", {}) logging_config = arrival.get("logging", {}) if isinstance(arrival, dict) else {} logging.basicConfig( level=getattr(logging, str(logging_config.get("level", "INFO")).upper()), format="%(asctime)s %(levelname)s %(message)s", ) return run(config, args.once) if __name__ == "__main__": raise SystemExit(main())