improve samtec autogeneration
This commit is contained in:
parent
cef4186044
commit
6d35a1f8a1
124
generate.py
124
generate.py
|
@ -1,27 +1,38 @@
|
|||
import time
|
||||
from multiprocessing import Pool
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import Optional, Union
|
||||
from zipfile import ZipFile
|
||||
|
||||
import numpy as np
|
||||
import regex as re
|
||||
from retry import retry
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.webdriver.support.select import By, Select
|
||||
from selenium.webdriver.support.select import By
|
||||
from selenium.webdriver.support.wait import WebDriverWait
|
||||
|
||||
dir_ = Path(__file__).parent
|
||||
rng = np.random.default_rng()
|
||||
|
||||
PARTS = [
|
||||
*[f"TSW-1{i:02d}-05-G-S" for i in range(1, 10)],
|
||||
*[f"TSW-1{i:02d}-07-L-S" for i in range(1, 50)],
|
||||
*[f"TSW-1{i:02d}-07-L-D" for i in range(1, 50)],
|
||||
*[f"TSW-1{i:02d}-07-L-T" for i in range(1, 50)],
|
||||
*[f"TSW-1{i:02d}-07-L-Q" for i in range(1, 50)],
|
||||
*[f"TSW-2{i:02d}-07-L-S" for i in range(2, 25)],
|
||||
*[f"TSW-2{i:02d}-07-L-D" for i in range(2, 25)],
|
||||
*[f"TSW-2{i:02d}-07-L-T" for i in range(2, 25)],
|
||||
*[f"TSW-2{i:02d}-07-L-Q" for i in range(2, 25)],
|
||||
]
|
||||
URL_STEP = "https://www.snapeda.com/parts/{0}/Samtec/embed/?ref=samtec"
|
||||
|
||||
|
||||
@retry(tries=2, delay=1)
|
||||
def download_step(part: str):
|
||||
# @retry(tries=10, delay=1)
|
||||
def download_step_samtec(part: str):
|
||||
print(part)
|
||||
with TemporaryDirectory(prefix=str(dir_ / "tmp")) as tmp:
|
||||
with TemporaryDirectory(prefix=str(dir_ / "tmp") + "/") as tmp:
|
||||
tmp = Path(tmp)
|
||||
|
||||
chrome_options = webdriver.ChromeOptions()
|
||||
|
@ -35,11 +46,9 @@ def download_step(part: str):
|
|||
options=chrome_options,
|
||||
) as browser:
|
||||
browser.get(URL_STEP.format(part.upper()))
|
||||
wait = WebDriverWait(browser, 10)
|
||||
wait = WebDriverWait(browser, 30)
|
||||
wait.until(
|
||||
EC.element_to_be_clickable(
|
||||
browser.find_element(by=By.ID, value="download_traceparts_3d_model")
|
||||
)
|
||||
EC.element_to_be_clickable(browser.find_element(by=By.ID, value="download_traceparts_3d_model"))
|
||||
).click()
|
||||
wait.until(
|
||||
EC.element_to_be_clickable(
|
||||
|
@ -53,6 +62,7 @@ def download_step(part: str):
|
|||
# wait for download to finish
|
||||
while len(list((Path(tmp).glob("*.zip")))) == 0:
|
||||
time.sleep(0.1)
|
||||
# print(list((Path(tmp).glob("*.zip"))))
|
||||
|
||||
# unzip
|
||||
with ZipFile(list((Path(tmp).glob("*.zip")))[0]) as zip:
|
||||
|
@ -60,8 +70,98 @@ def download_step(part: str):
|
|||
|
||||
# move
|
||||
filename = f"{part.upper()}.stp"
|
||||
(Path(tmp) / filename).rename(dir_ / "3dshapes" / filename)
|
||||
# if filename not in list(Path(tmp).glob("*.stp")):
|
||||
# raise ValueError(
|
||||
# f"Name mismatch: {filename} does not exist. Found {[f.name for f in list(Path(tmp).glob('*.stp'))]}"
|
||||
# )
|
||||
(Path(tmp) / filename).rename(dir_ / "samtec.pretty" / "3dshapes" / filename)
|
||||
|
||||
|
||||
now = datetime.now()
|
||||
INCH = 25.4
|
||||
SILK_WIDTH = 0.007 * INCH
|
||||
|
||||
|
||||
def footprint_samtec(part: str, lib: Optional[Union[Path, str]] = None) -> str:
|
||||
if part[:4].upper() == "TSW-":
|
||||
# pinheader
|
||||
match = re.match(
|
||||
r"(H?)TSW-([12])(\d\d)-(\d\d)-([FLGT])-([SDTQ])(-RA)?(-RE)?(-NA)?(-LL)?(-LC)?(-LA)?(-(\d\d\d))?",
|
||||
part.upper(),
|
||||
)
|
||||
high_temp = match[1] != ""
|
||||
spacing = int(match[2])
|
||||
rows = int(match[3])
|
||||
# lead_style = {
|
||||
# 5:
|
||||
# }[int(match[4])]
|
||||
plating = {
|
||||
"F": "Gold flash on post, Matte Tin on tail",
|
||||
"L": '10 µ" (0.25 µm) Gold on post, Matte Tin on tail',
|
||||
"G": '10 µ" (0.25 µm) Gold on post, Gold flash on balance',
|
||||
"T": "Matte Tin",
|
||||
}[match[5]]
|
||||
cols = {"S": 1, "D": 2, "T": 3, "Q": 4}[match[6]]
|
||||
|
||||
strobe = [(2 if cols == 4 else 1) * 0.1 * INCH, spacing * 0.1 * INCH]
|
||||
if cols == 4:
|
||||
# only outer columns filled
|
||||
cols = 2
|
||||
fp_name = f"PinHeader_{cols}x{rows:02d}_0.1in_{part}"
|
||||
hole_diam = 0.040 * INCH
|
||||
pad_size = 0.075 * INCH
|
||||
|
||||
center = [strobe[0] * (cols - 1) / 2, strobe[1] * (rows - 1) / 2]
|
||||
|
||||
if lib is None:
|
||||
lib = dir_ / "samtec.pretty"
|
||||
lib = Path(lib)
|
||||
with open(lib / f"{fp_name}.kicad_mod", "w") as f:
|
||||
f.write(
|
||||
"\n".join(
|
||||
(
|
||||
f'(footprint "{fp_name}" (version {now.strftime("%Y%m%d")}) (generator pcbnew) (layer "F.Cu")',
|
||||
r" (attr through_hole)",
|
||||
f' (fp_text reference "REF**" (at {center[0]} {-2.032}) (layer "F.SilkS")',
|
||||
r" (effects (font (size 0.762 0.762) (thickness 0.127)))",
|
||||
r" )",
|
||||
f' (fp_text value "VAL**" (at {center[0]} {center[1]} 90) (layer "F.Fab") hide',
|
||||
r" (effects (font (size 0.762 0.762) (thickness 0.127)))",
|
||||
r" )",
|
||||
r' (fp_text user "${REFERENCE}" ' f'(at {center[0]} {center[1]} 90) (layer "F.Fab")',
|
||||
r" (effects (font (size 1 1) (thickness 0.15)))",
|
||||
r" )",
|
||||
f" (fp_rect (start {-0.05 * INCH} {-0.05 * INCH}) (end {0.05 * INCH + strobe[0] * (cols - 1)} {0.05 * INCH + strobe[1] * (rows - 1)})",
|
||||
f' (stroke (width {SILK_WIDTH}) (type default)) (fill none) (layer "F.SilkS")' r" )",
|
||||
f' (fp_line (start {-0.05 * INCH} {0.05 * INCH}) (end {0.05 * INCH} {0.05 * INCH}) (layer "F.SilkS") (width {SILK_WIDTH}))',
|
||||
f' (fp_line (start {0.05 * INCH} {-0.05 * INCH}) (end {0.05 * INCH} {0.05 * INCH}) (layer "F.SilkS") (width {SILK_WIDTH}))',
|
||||
*[
|
||||
f' (pad "{pad + 1}" thru_hole {"rect" if pad == 0 else "circle"} '
|
||||
f"(at {strobe[0] * (pad % cols)} {strobe[1] * int(pad / cols)}) (size {pad_size} {pad_size}) (drill {hole_diam}) (layers *.Cu *.Mask))"
|
||||
for pad in range(rows * cols)
|
||||
],
|
||||
f' (model "/home/brendan/Documents/projects/kicad/samtec.pretty/3dshapes/{part}.stp"',
|
||||
f" (offset (xyz {center[0]} {-center[1]} 0))",
|
||||
r" (scale (xyz 1 1 1))",
|
||||
r" (rotate (xyz -90 0 90))",
|
||||
r" )",
|
||||
r")",
|
||||
)
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"Unknown part family for {part}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
for part in PARTS:
|
||||
download_step(part)
|
||||
time.sleep(rng.random() * 3)
|
||||
download_step_samtec(part)
|
||||
footprint_samtec(part)
|
||||
|
||||
# from multiprocessing import Pool
|
||||
# pool = Pool(10)
|
||||
# pool.map(download_step_samtec, PARTS)
|
||||
# pool.map(footprint_samtec, PARTS)
|
||||
# pool.close()
|
||||
|
|
17
pyproject.toml
Executable file
17
pyproject.toml
Executable file
|
@ -0,0 +1,17 @@
|
|||
[build-system]
|
||||
requires = [
|
||||
"setuptools>=42",
|
||||
"wheel"
|
||||
]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.pylint.messages_control]
|
||||
disable = "C0330, C0326"
|
||||
|
||||
[tool.pylint.format]
|
||||
max-line-length = "100"
|
||||
|
||||
[tool.black]
|
||||
line-length = 120
|
||||
organize-imports = true
|
||||
target-version = ['py38']
|
Loading…
Reference in New Issue
Block a user