Recover ferrite bead Z from datasheet evidence without aborting graph_build.

This commit is contained in:
2026-09-21 00:19:06 +02:00
parent 51c09b2176
commit a2d5900b64
13 changed files with 279 additions and 27 deletions
+50 -8
View File
@@ -1,4 +1,4 @@
"""Ferrite beads without Z validate; other inductors still need henries."""
"""Ferrite beads: recover Z from evidence; never invent; never abort ingest."""
from __future__ import annotations
@@ -8,25 +8,26 @@ from pathlib import Path
import pytest
from pydantic import ValidationError
from backend.periscopex.ferrite_z import recover_bead_specs, z_from_datasheet_text
from backend.periscopex.graph import _load_component_models
from backend.periscopex.models import ComponentModel, InductorSpecs
from backend.periscopex.models import ComponentModel, InductorSpecs, SimpleComponentSpecs
from backend.periscopex.resolve_passives import simple_to_typed_passive_specs
from backend.periscopex.models import SimpleComponentSpecs
def test_ferrite_bead_without_impedance_ohm_validates():
def test_ferrite_bead_quoted_ohm_fills_z_not_henries():
specs = InductorSpecs(
component_subtype="passive.ferrite_bead",
value_formatted="120 ohm @ 100 MHz",
current_rating_a="3A",
dcr_ohms=0.03,
)
assert specs.impedance_ohm is None
assert specs.impedance_ohm == 120.0
assert specs.value_henries is None
model = ComponentModel(mpn="BLM21PG121SN1D", specs=specs)
assert model.specs.impedance_ohm is None
assert model.specs.impedance_ohm == 120.0
def test_ferrite_bead_live_payload_without_z_validates():
def test_ferrite_bead_live_payload_fills_z_from_formatted():
model = ComponentModel.model_validate({
"mpn": "BLM21PG121SN1D",
"specs": {
@@ -40,7 +41,8 @@ def test_ferrite_bead_live_payload_without_z_validates():
"dcr_ohms": 0.03,
},
})
assert model.specs.impedance_ohm is None
assert model.specs.impedance_ohm == 120.0
assert model.specs.value_henries is None
assert model.specs.current_rating_a == "3A"
assert model.specs.dcr_ohms == 0.03
@@ -54,6 +56,7 @@ def test_ferrite_bead_with_impedance_ohm_still_ok():
dcr_ohms=0.03,
)
assert specs.impedance_ohm == 120.0
assert specs.value_henries is None
def test_inductor_still_requires_value_henries():
@@ -105,3 +108,42 @@ def test_simple_to_typed_bead_without_z():
assert specs.specs_type == "inductor"
assert specs.impedance_ohm is None
assert specs.dcr_ohms == 0.03
def test_bead_mpn_datasheet_text_fills_z():
text = (
"BLM21PG121SN1D chip ferrite bead\n"
"Impedance (at 100MHz / 20°C) 120 ohm\n"
"Rated current 3A\n"
"DC resistance 0.03 ohm\n"
)
hit = z_from_datasheet_text(text)
assert hit is not None
z, formatted = hit
assert z == 120.0
assert "100" in formatted
assert "datasheet" in formatted
specs = InductorSpecs(
component_subtype="passive.ferrite_bead",
value_formatted="FB",
current_rating_a="3A",
dcr_ohms=0.03,
)
filled = recover_bead_specs(specs, extra_text=text)
assert filled.impedance_ohm == 120.0
assert filled.value_henries is None
def test_bead_mpn_datasheet_without_z_does_not_invent():
text = "BLM21PG121SN1D\nRated current 3 A\nDCR 0.03 ohm max\nPackage 0805"
assert z_from_datasheet_text(text) is None
specs = InductorSpecs(
component_subtype="passive.ferrite_bead",
value_formatted="FB",
current_rating_a="3A",
dcr_ohms=0.03,
)
filled = recover_bead_specs(specs, extra_text=text)
assert filled.impedance_ohm is None
model = ComponentModel(mpn="BLM21PG121SN1D", specs=filled)
assert model.specs.impedance_ohm is None
+1 -1
View File
@@ -61,6 +61,6 @@ def test_skills_manifest_bumped_for_prompt_change():
text = (ROOT / "periscope" / "src" / "backend" / "skills_manifest.json").read_text(
encoding="utf-8"
)
assert '"default_model_version": "1.14.0"' in text
assert '"default_model_version": "1.15.0"' in text
validate = load_skill_validator("extract-pintable")
assert validate is not None