"""Filesystem loader for the seed library. Resolves paths inside the installed ``arautopilot.library`` package and deserialises actuator profiles (JSON) and default PID tunings (YAML). """ from __future__ import annotations import json from importlib import resources from pathlib import Path from typing import Any import yaml from arautopilot.core.actuator_config import ActuatorConfig from arautopilot.core.pid_config import PidConfig _ACTUATOR_PACKAGE = "arautopilot.library.actuators" _TUNINGS_PACKAGE = "arautopilot.library.default_tunings" def list_actuator_profiles() -> list[str]: """Return the IDs (filename stems) of all bundled actuator profiles.""" return sorted( r.name.removesuffix(".json") for r in resources.files(_ACTUATOR_PACKAGE).iterdir() if r.is_file() and r.name.endswith(".json") ) def list_default_tunings() -> list[str]: """Return the IDs (filename stems) of all bundled default tunings.""" return sorted( r.name.removesuffix(".yaml") for r in resources.files(_TUNINGS_PACKAGE).iterdir() if r.is_file() and r.name.endswith(".yaml") ) def load_actuator_profile(profile_id: str) -> ActuatorConfig: """Load and validate one bundled actuator profile by ID.""" data = _read_json_resource(_ACTUATOR_PACKAGE, f"{profile_id}.json") return ActuatorConfig.model_validate(data) def load_default_tuning(tuning_id: str) -> PidConfig: """Load and validate one bundled default PID tuning by ID.""" data = _read_yaml_resource(_TUNINGS_PACKAGE, f"{tuning_id}.yaml") return PidConfig.model_validate(data) def load_actuator_profile_from_path(path: Path | str) -> ActuatorConfig: """Load an actuator profile from an arbitrary filesystem path (for tests / Studio).""" p = Path(path) with p.open("r", encoding="utf-8") as f: return ActuatorConfig.model_validate(json.load(f)) def load_default_tuning_from_path(path: Path | str) -> PidConfig: """Load a default PID tuning from an arbitrary filesystem path (for tests / Studio).""" p = Path(path) with p.open("r", encoding="utf-8") as f: return PidConfig.model_validate(yaml.safe_load(f)) def _read_json_resource(package: str, filename: str) -> dict[str, Any]: return json.loads(resources.files(package).joinpath(filename).read_text(encoding="utf-8")) def _read_yaml_resource(package: str, filename: str) -> dict[str, Any]: return yaml.safe_load( resources.files(package).joinpath(filename).read_text(encoding="utf-8") )