Treat KiCad Value/PNM as the IC MPN when the MPN column is empty.
Those 13 U* were in the BOM (TPS22965, TPD2E007, TMP117, …) but never entered ic_mpns, so review skipped them as missing PDFs. Also try the BOM Datasheet URL first. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -382,10 +382,13 @@ async def _from_digikey(mpn: str) -> DatasheetHit | None:
|
||||
return DatasheetHit(mpn, error=result.error, url=result.url, source="digikey")
|
||||
|
||||
|
||||
async def find_datasheet(mpn: str, lcsc_id: str | None = None) -> DatasheetHit:
|
||||
async def find_datasheet(
|
||||
mpn: str, lcsc_id: str | None = None, url_hint: str | None = None,
|
||||
) -> DatasheetHit:
|
||||
"""Find and download a datasheet PDF for ``mpn``.
|
||||
|
||||
Tries LCSC, then TI (when the MPN looks like a TI part), then DigiKey.
|
||||
Tries an explicit BOM URL first, then LCSC, then TI (when the MPN
|
||||
looks like a TI part), then DigiKey.
|
||||
"""
|
||||
mpn = (mpn or "").strip()
|
||||
if not mpn:
|
||||
@@ -394,6 +397,16 @@ async def find_datasheet(mpn: str, lcsc_id: str | None = None) -> DatasheetHit:
|
||||
errors: list[str] = []
|
||||
last_url: str | None = None
|
||||
|
||||
hint = (url_hint or "").strip()
|
||||
if hint.startswith("http"):
|
||||
try:
|
||||
pdf = await _download_pdf(hint)
|
||||
return DatasheetHit(mpn, pdf_bytes=pdf, url=hint, source="bom")
|
||||
except Exception as exc:
|
||||
log.info("BOM datasheet URL missed %s: %s", mpn, exc)
|
||||
errors.append(f"bom: {exc}")
|
||||
last_url = hint
|
||||
|
||||
for source_fn in (_from_lcsc, _from_ti, _from_digikey):
|
||||
try:
|
||||
if source_fn is _from_lcsc:
|
||||
|
||||
@@ -369,7 +369,7 @@ class PipelineContext:
|
||||
# the primary numeric value from here without saving to the shared library.
|
||||
passive_values: dict[str, str] = field(default_factory=dict)
|
||||
simple_mpns: dict[str, list[str]] = field(default_factory=dict)
|
||||
simple_mpn_types: dict[str, str] = field(default_factory=dict)
|
||||
datasheet_urls: dict[str, str] = field(default_factory=dict)
|
||||
# Cached purple-parts payload (description, category, subcategory, manufacturer,
|
||||
# package, ...) keyed by *resolved* MPN. Populated by _resolve_lcsc_codes during
|
||||
# BOM parse; consumed by passive extraction as a first-pass auto-resolve source
|
||||
@@ -605,6 +605,9 @@ async def _stage_bom_parse(ctx: PipelineContext) -> None:
|
||||
|
||||
for ref, info in sorted(bom.items()):
|
||||
mpn = info.get("mpn")
|
||||
url = (info.get("datasheet_url") or "").strip()
|
||||
if mpn and url and mpn not in ctx.datasheet_urls:
|
||||
ctx.datasheet_urls[mpn] = url
|
||||
if not mpn:
|
||||
continue
|
||||
typ = type_for_ref(ref)
|
||||
@@ -705,7 +708,11 @@ async def _ensure_local_datasheet(
|
||||
{"stage": stage, "substep": mpn,
|
||||
"status": "running", "detail": "finding datasheet"},
|
||||
)
|
||||
hit = await find_datasheet(mpn, lcsc_id=_lcsc_id_for_mpn(ctx, mpn))
|
||||
hit = await find_datasheet(
|
||||
mpn,
|
||||
lcsc_id=_lcsc_id_for_mpn(ctx, mpn),
|
||||
url_hint=ctx.datasheet_urls.get(mpn),
|
||||
)
|
||||
if not hit.ok or not hit.pdf_bytes:
|
||||
return False
|
||||
pdf_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
Reference in New Issue
Block a user