pixalynx/pixal-gps

These files define two separate printed circuit boards: a small, two-layer battery cartridge with protection circuitry and contact pads for a pouch cell, and a larger, two-layer wireless charging dock featuring USB-C input, a resonant coil, and wireless power transmission components.

Version
0.1.2
License
unset
Stars
0

scripts/bom.py

#!/usr/bin/env python3
"""Emit a grouped BOM (markdown) for each built board from its Circuit JSON."""
import json, sys, collections
boards = sys.argv[1:] or ["tracker", "battery-pack", "dock"]
out = ["# Bill of materials (generated by scripts/bom.py from the built Circuit JSON)", "",
       "JLCPCB part numbers were resolved on 14 September 2026 (see docs/sources.md); DNP = footprint present, not populated. Quantities are per board.", ""]
for b in boards:
    d = json.load(open(f"dist/{b}/circuit.json"))
    groups = collections.OrderedDict()
    pcb = {p["source_component_id"]: p for p in d if p["type"] == "pcb_component"}
    for c in d:
        if c["type"] != "source_component": continue
        val = c.get("manufacturer_part_number") or c.get("display_resistance") or c.get("display_capacitance") or c.get("display_inductance") or ""
        sup = (c.get("supplier_part_numbers") or {}).get("jlcpcb", [])
        p = pcb.get(c["source_component_id"], {})
        fp = f"{p['width']:.1f} x {p['height']:.1f} mm, {p.get('layer','top')}" if p else ""
        dnp = bool(p.get("do_not_place"))
        key = (c.get("ftype", ""), str(val), fp, ",".join(sup), dnp)
        groups.setdefault(key, []).append(c["name"])
    out += [f"## {b}", "", "| Qty | Refs | Type | Value / MPN | Footprint | JLCPCB | DNP |", "| --- | --- | --- | --- | --- | --- | --- |"]
    for (ft, val, fp, sup, dnp), refs in sorted(groups.items(), key=lambda kv: (kv[0][0], kv[1][0])):
        out.append(f"| {len(refs)} | {', '.join(sorted(refs, key=lambda s: (s.rstrip('0123456789'), int(''.join(ch for ch in s if ch.isdigit()) or 0))))} | {ft.replace('simple_', '')} | {val} | {fp} | {sup} | {'yes' if dnp else ''} |")
    out.append("")
open("docs/bom.md", "w").write("\n".join(out))
print("docs/bom.md written")