Fill ferrite bead impedance from the MPN datasheet PDF.
graph_build searches project uploads and library blob refs, persists recovered Z, and still loads when the PDF has no impedance. Ohms are not written to henries.
This commit is contained in:
@@ -147,3 +147,109 @@ def test_bead_mpn_datasheet_without_z_does_not_invent():
|
||||
assert filled.impedance_ohm is None
|
||||
model = ComponentModel(mpn="BLM21PG121SN1D", specs=filled)
|
||||
assert model.specs.impedance_ohm is None
|
||||
|
||||
|
||||
def _write_text_pdf(path: Path, text: str) -> None:
|
||||
"""Write a one-page PDF pypdf can extract without PyMuPDF."""
|
||||
escaped = (
|
||||
text.replace("\\", "\\\\").replace("(", "\\(").replace(")", "\\)")
|
||||
)
|
||||
lines = escaped.split("\n")
|
||||
ops = ["BT /F1 12 Tf 72 720 Td"]
|
||||
for i, line in enumerate(lines):
|
||||
if i:
|
||||
ops.append("0 -16 Td")
|
||||
ops.append(f"({line}) Tj")
|
||||
ops.append("ET")
|
||||
stream = "\n".join(ops).encode("latin-1", "replace")
|
||||
objects = [
|
||||
b"1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj\n",
|
||||
b"2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj\n",
|
||||
(
|
||||
b"3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] "
|
||||
b"/Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >> endobj\n"
|
||||
),
|
||||
b"4 0 obj << /Length %d >> stream\n" % len(stream) + stream + b"\nendstream endobj\n",
|
||||
b"5 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> endobj\n",
|
||||
]
|
||||
header = b"%PDF-1.4\n"
|
||||
body = header
|
||||
offsets = [0]
|
||||
for obj in objects:
|
||||
offsets.append(len(body))
|
||||
body += obj
|
||||
xref_pos = len(body)
|
||||
xref = [b"xref\n0 6\n0000000000 65535 f \n"]
|
||||
for off in offsets[1:]:
|
||||
xref.append(f"{off:010d} 00000 n \n".encode())
|
||||
trailer = (
|
||||
b"trailer << /Root 1 0 R /Size 6 >>\nstartxref\n"
|
||||
+ str(xref_pos).encode()
|
||||
+ b"\n%%EOF\n"
|
||||
)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_bytes(body + b"".join(xref) + trailer)
|
||||
|
||||
|
||||
_BEAD_MODEL = {
|
||||
"mpn": "BLM21PG121SN1D",
|
||||
"specs": {
|
||||
"specs_type": "inductor",
|
||||
"component_subtype": "passive.ferrite_bead",
|
||||
"value_formatted": "FB",
|
||||
"current_rating_a": "3A",
|
||||
"dcr_ohms": 0.03,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_bead_mpn_datasheet_pdf_fills_z(tmp_path: Path):
|
||||
models = tmp_path / "models"
|
||||
models.mkdir()
|
||||
(models / "BLM21PG121SN1D.json").write_text(json.dumps(_BEAD_MODEL) + "\n")
|
||||
_write_text_pdf(
|
||||
tmp_path / "uploads" / "datasheets" / "BLM21PG121SN1D.pdf",
|
||||
"BLM21PG121SN1D\nImpedance (at 100MHz / 20C) 120 ohm\nRated current 3A",
|
||||
)
|
||||
loaded = _load_component_models(models)
|
||||
assert loaded["BLM21PG121SN1D"].impedance_ohm == 120.0
|
||||
assert loaded["BLM21PG121SN1D"].value_henries is None
|
||||
persisted = json.loads((models / "BLM21PG121SN1D.json").read_text())
|
||||
assert persisted["specs"]["impedance_ohm"] == 120.0
|
||||
assert persisted["specs"]["value_henries"] is None
|
||||
assert "100" in (persisted["specs"].get("value_formatted") or "")
|
||||
|
||||
|
||||
def test_bead_mpn_datasheet_pdf_without_z_does_not_invent(tmp_path: Path):
|
||||
models = tmp_path / "models"
|
||||
models.mkdir()
|
||||
(models / "BLM21PG121SN1D.json").write_text(json.dumps(_BEAD_MODEL) + "\n")
|
||||
_write_text_pdf(
|
||||
tmp_path / "uploads" / "datasheets" / "BLM21PG121SN1D.pdf",
|
||||
"BLM21PG121SN1D\nRated current 3 A\nDCR 0.03 ohm max\nPackage 0805",
|
||||
)
|
||||
loaded = _load_component_models(models)
|
||||
assert "BLM21PG121SN1D" in loaded
|
||||
assert loaded["BLM21PG121SN1D"].impedance_ohm is None
|
||||
assert loaded["BLM21PG121SN1D"].value_henries is None
|
||||
|
||||
|
||||
def test_bead_mpn_library_blob_fills_z(tmp_path: Path):
|
||||
models = tmp_path / "proj" / "models"
|
||||
models.mkdir(parents=True)
|
||||
(models / "BLM21PG121SN1D.json").write_text(json.dumps(_BEAD_MODEL) + "\n")
|
||||
blob = tmp_path / "library" / "datasheets" / "blobs" / "deadbeef.pdf"
|
||||
_write_text_pdf(
|
||||
blob,
|
||||
"Impedance (at 100MHz / 20C) 120 ohm\nRated current 3A",
|
||||
)
|
||||
ref = tmp_path / "library" / "datasheets" / "refs" / "BLM21PG121SN1D.json"
|
||||
ref.parent.mkdir(parents=True, exist_ok=True)
|
||||
ref.write_text(json.dumps({
|
||||
"hash": "deadbeef",
|
||||
"blob_key": "library/datasheets/blobs/deadbeef.pdf",
|
||||
"mpn": "BLM21PG121SN1D",
|
||||
}) + "\n")
|
||||
loaded = _load_component_models(models, extra_pdf_dirs=[tmp_path])
|
||||
assert loaded["BLM21PG121SN1D"].impedance_ohm == 120.0
|
||||
assert loaded["BLM21PG121SN1D"].value_henries is None
|
||||
|
||||
Reference in New Issue
Block a user