8d4a698144
Run the dev linters over Sprint 0's core/library/shared modules and address every finding. Behaviour unchanged; tests still 80/80 green. Changes: - Replace `class Foo(str, Enum)` with `class Foo(StrEnum)` (PEP 663 / Python 3.11+) in 7 enum classes: ActuatorType, AlarmSeverity, AlarmType, KnobMode, KnobFunction, AutopilotMode, AccessLevel, VesselType. Pydantic v2 serialises StrEnum the same way, so YAML/JSON round-trips are byte-identical. - Use `datetime.UTC` alias in place of `datetime.timezone.utc` (UP017) across alarms.py, knob_state.py, project_config.py, and test_knob_state.py. - Remove now-unnecessary forward-reference quotes from method return type annotations (UP037) — `from __future__ import annotations` is already in scope everywhere. - Tighten `_read_json_resource` / `_read_yaml_resource` in the library loader: validate that the deserialised payload is actually a dict before returning, instead of leaking `Any` from json.loads / yaml.safe_load. Fixes the only two `mypy --strict` findings. - Add `.claude/settings.local.json` to .gitignore (personal Claude Code overrides are not committed). Verification: ruff check arautopilot/ -> All checks passed mypy arautopilot/core library shared -> Success, 0 issues, 12 files pytest -> 80 passed in 0.25s Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
63 lines
1.8 KiB
Python
63 lines
1.8 KiB
Python
"""Per-vessel configuration: identification + actuator + PID.
|
|
|
|
Composes the lower-level configs into one object that lives at the heart
|
|
of every ``ProjectConfig``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from enum import StrEnum
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
from arautopilot.core.actuator_config import ActuatorConfig
|
|
from arautopilot.core.ids import VesselId, new_vessel_id
|
|
from arautopilot.core.pid_config import PidConfig
|
|
|
|
|
|
class VesselType(StrEnum):
|
|
"""Vessel classes targeted by Phase 1 of the product (brief section 3)."""
|
|
|
|
YACHT_MOTOR_PLANEO = "yacht_motor_planeo"
|
|
"""Planing motor yacht, 30-40 m."""
|
|
|
|
YACHT_MOTOR_DESPLAZAMIENTO = "yacht_motor_desplazamiento"
|
|
"""Displacement motor yacht, 30-40 m."""
|
|
|
|
SAILBOAT_MOTOR = "sailboat_motor"
|
|
"""Sailing yacht under motor (no sail trim). Phase 1 only."""
|
|
|
|
FISHING_BOAT = "fishing_boat"
|
|
"""Fishing vessel, 30 m class."""
|
|
|
|
SMALL_FERRY = "small_ferry"
|
|
"""Small ferry, 30 m class."""
|
|
|
|
PATROL_BOAT = "patrol_boat"
|
|
"""Coastal patrol boat, 30 m class."""
|
|
|
|
|
|
class VesselConfig(BaseModel):
|
|
"""Identification, geometry, and control configuration of one vessel."""
|
|
|
|
model_config = ConfigDict(extra="forbid", validate_assignment=True)
|
|
|
|
vessel_id: VesselId = Field(default_factory=new_vessel_id)
|
|
name: str = Field(min_length=1, max_length=120)
|
|
type: VesselType
|
|
length_m: float = Field(gt=0.0, le=200.0, description="Length overall, metres.")
|
|
displacement_t: float = Field(
|
|
default=0.0,
|
|
ge=0.0,
|
|
le=10_000.0,
|
|
description="Loaded displacement, tonnes. 0 means unknown.",
|
|
)
|
|
max_speed_kn: float = Field(
|
|
gt=0.0,
|
|
le=80.0,
|
|
description="Maximum design speed over ground, knots.",
|
|
)
|
|
|
|
actuator: ActuatorConfig
|
|
pid: PidConfig
|