""" Physical patch panel: front-panel position count for the rack (field workflow). Stored in fiber_map.json as ``patch_panel``: ``{ "slots": N, "label": "…" }``. USB hub calibrate still walks hub ports; map keys 1…N align with panel positions. """ from __future__ import annotations from dataclasses import dataclass from typing import Any, Dict, Optional from fiwi.constants import PANEL_SLOTS _MAX_SLOTS = 256 @dataclass(frozen=True) class PatchPanel: """Instantiated panel: ``slots`` front-panel positions (numbered 1…slots).""" slots: int label: str = "" def __post_init__(self) -> None: if self.slots < 1: raise ValueError("patch panel slots must be >= 1") if self.slots > _MAX_SLOTS: raise ValueError(f"patch panel slots must be <= {_MAX_SLOTS}") def to_map_blob(self) -> Dict[str, Any]: d: Dict[str, Any] = {"slots": self.slots} if self.label.strip(): d["label"] = self.label.strip() return d @classmethod def from_map_blob(cls, blob: Any) -> Optional[PatchPanel]: if not isinstance(blob, dict): return None s = blob.get("slots") if isinstance(s, str) and s.strip().isdigit(): s = int(s.strip()) if not isinstance(s, int) or s < 1: return None if s > _MAX_SLOTS: return None lab = blob.get("label") label = lab.strip() if isinstance(lab, str) else "" return cls(slots=s, label=label) def effective_panel_slots(doc: Optional[Dict[str, Any]]) -> int: """Panel position count from ``doc['patch_panel']``, else ``PANEL_SLOTS``.""" if not isinstance(doc, dict): return PANEL_SLOTS pp = PatchPanel.from_map_blob(doc.get("patch_panel")) if pp is not None: return pp.slots return PANEL_SLOTS