component
Wurth 61300411121 (WR-PHD 1x04 2.54 mm pin header)
Public Made by Adomby adom
Wurth Elektronik WR-PHD 61300411121: 4-pin, 2.54 mm, single-row THT vertical pin header, gold, 3 A. KiCad symbol, footprint at the datasheet's 1.10 mm hole, and KiCad's generic 1x04 header 3D model checked against the drawing.
main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
#!/usr/bin/env python3
"""Derive the wiki page's KiCad symbol and footprint for Wurth Elektronik 61300411121 from the project
library files the board uses, changing only identity text (names, model path, generic description, order
numbers). Geometry, pads, drills, graphics and pins are copied unchanged; compare_cad() proves it.
make_cad.py <board .kicad_sym> <board .kicad_mod> <out dir>
"""
import hashlib, json, re, sys
MPN = "61300411121"
FIELDS = [ # added after Manufacturer, in this order, hidden
("Mouser", "710-61300411121"),
("DigiKey", "732-5317-ND"),
("LCSC", "C5184785"),
("Adom Wiki", "https://wiki.adom.inc/adom/61300411121"),
]
DESC = ("Wurth Elektronik WR-PHD 61300411121 pin header, 2.54 mm pitch, 1x04, THT vertical, "
"gold-plated 0.64 mm square pins, 3 A, 250 VAC")
def block(text, head):
i = text.find(head)
if i < 0:
raise SystemExit(f"not found: {head}")
d = 0
for j in range(i, len(text)):
if text[j] == "(":
d += 1
elif text[j] == ")":
d -= 1
if d == 0:
return text[i:j + 1]
raise SystemExit("unbalanced")
def prop(name, value, indent="\t\t"):
return (f'{indent}(property "{name}" "{value}"\n'
f'{indent}\t(at 0 0 0)\n{indent}\t(show_name no)\n{indent}\t(do_not_autoplace no)\n'
f'{indent}\t(hide yes)\n{indent}\t(effects\n{indent}\t\t(font\n{indent}\t\t\t(size 1.27 1.27)\n'
f'{indent}\t\t)\n{indent}\t)\n{indent})\n')
def make_symbol(src):
s = open(src).read()
sym = block(s, f'(symbol "{MPN}"')
sym = sym.replace('(property "Footprint" "fc_local:WE_61300411121_1x04_P2.54mm_Vertical"',
f'(property "Footprint" "{MPN}:{MPN}"', 1)
sym, n = re.subn(r'\(property "Description" "[^"]*"', f'(property "Description" "{DESC}"', sym, count=1)
assert n == 1
# insert the order fields after the Manufacturer property block
m = re.search(r'\t\t\(property "Manufacturer" "[^"]*"\n(?:.*\n)*?\t\t\)\n', "\t" + sym)
assert m, "Manufacturer property not found"
ins = "".join(prop(k, v) for k, v in FIELDS)
sym = ("\t" + sym)[:m.end()] + ins + ("\t" + sym)[m.end():]
head = ('(kicad_symbol_lib\n\t(version 20251024)\n\t(generator "kicad_symbol_editor")\n'
'\t(generator_version "10.0")\n')
return head + sym + "\n)\n"
def make_footprint(src):
f = open(src).read()
f = f.replace('(footprint "WE_61300411121_1x04_P2.54mm_Vertical"', f'(footprint "{MPN}"', 1)
f = f.replace('(model "${KIPRJMOD}/lib/fc_local.3dshapes/WE_61300411121.step"',
'(model "${KIPRJMOD}/' + MPN + '.step"', 1)
return f
def geometry(text):
"""Everything that is not identity text: pads, graphics, pins, layers."""
out = []
for line in text.splitlines():
t = line.strip()
if re.match(r'\((footprint|symbol|property|descr|model|kicad_symbol_lib|version|generator)\b', t):
out.append("<id>")
continue
out.append(t)
return out
def main():
sym_src, fp_src, out = sys.argv[1:4]
sym = make_symbol(sym_src)
fp = make_footprint(fp_src)
open(f"{out}/{MPN}.kicad_sym", "w").write(sym)
open(f"{out}/{MPN}.kicad_mod", "w").write(fp)
# pads and graphics unchanged? compare the footprint line by line outside identity lines
fsrc = open(fp_src).read()
same_fp = [a for a in zip(fsrc.splitlines(), fp.splitlines()) if a[0] != a[1]]
print(json.dumps({
"footprint_lines_changed": [{"board": a, "page": b} for a, b in same_fp],
"symbol_pins": re.findall(r'\(pin (\w+) line\s*\n\s*\(at ([^)]*)\)\s*\n\s*\(length ([^)]*)\)\s*\n\s*\(name "([^"]*)"(?:.|\n)*?\(number "([^"]*)"', sym),
"sha256": {
"board_symbol_lib": hashlib.sha256(open(sym_src, "rb").read()).hexdigest(),
"board_footprint": hashlib.sha256(open(fp_src, "rb").read()).hexdigest(),
"page_symbol": hashlib.sha256(sym.encode()).hexdigest(),
"page_footprint": hashlib.sha256(fp.encode()).hexdigest(),
},
}, indent=1))
if __name__ == "__main__":
main()