173 lines
5.6 KiB
Python
173 lines
5.6 KiB
Python
# yes we are using json because
|
|
# i dont want to install a yaml
|
|
# parser on the users computer
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import csv
|
|
from enum import Enum
|
|
from pathlib import Path
|
|
from os import listdir
|
|
from os.path import isfile, join
|
|
|
|
KICAD_CLI_PATH = "kicad-cli"
|
|
TEMP_FILE_PATH = "temp/"
|
|
|
|
PCB_IMAGE_OUTPUT_PATH = "res/"
|
|
|
|
PCB_PDF_OUTPUT_PATH = "docs/"
|
|
PCB_PDF_FILE_SUFFIX = "_pcb"
|
|
|
|
SCHEMATIC_OUTPUT_PATH = "docs/"
|
|
SCHEMATIC_FILE_SUFFIX = "_schematic"
|
|
|
|
|
|
|
|
TEMP_DRC_REPORT_NAME = "_drc"
|
|
TEMP_ERC_REPORT_NAME = "_erc"
|
|
TEMP_BOM_REPORT_NAME = "_bom"
|
|
|
|
|
|
|
|
class OutputReportType(Enum):
|
|
JSON = 1
|
|
RPT = 2
|
|
|
|
# this is a thin vale on the kicad cli tool
|
|
class KicadProject:
|
|
|
|
def __init__(self, path : Path) -> None:
|
|
self.project_path = path.parent
|
|
self.project_name = path.name.removesuffix(".kicad_pro")
|
|
print(f"{self.project_path=}")
|
|
print(f"{self.project_name=}")
|
|
|
|
def erc_check(
|
|
self,
|
|
report_format : OutputReportType = OutputReportType.JSON,
|
|
return_report : bool = False
|
|
) -> None | dict | str:
|
|
format_type = report_format.name.lower()
|
|
pcb_file_path = self.project_path / f"{self.project_name}.kicad_sch"
|
|
erc_report_path = Path(TEMP_FILE_PATH) / f"{self.project_name}{TEMP_ERC_REPORT_NAME}.{format_type}"
|
|
subprocess.call(
|
|
f'{KICAD_CLI_PATH} sch erc {pcb_file_path} --output {erc_report_path} --format {format_type}',
|
|
shell=True,
|
|
)
|
|
|
|
if (return_report):
|
|
with open(erc_report_path, "r") as txt:
|
|
if format_type == OutputReportType.JSON:
|
|
return json.loads(txt.read())
|
|
if format_type == OutputReportType.RPT:
|
|
return txt.read()
|
|
|
|
def drc_check(
|
|
self,
|
|
report_format : OutputReportType = OutputReportType.JSON,
|
|
return_report : bool = False
|
|
) -> None | dict | str:
|
|
format_type = report_format.name.lower()
|
|
pcb_file_path = self.project_path / f"{self.project_name}.kicad_pcb"
|
|
drc_report_path = Path(TEMP_FILE_PATH) / f"{self.project_name}{TEMP_DRC_REPORT_NAME}.{format_type}"
|
|
subprocess.call(
|
|
f'{KICAD_CLI_PATH} pcb drc {pcb_file_path} --output {drc_report_path} --format {format_type}',
|
|
shell=True,
|
|
)
|
|
|
|
if (return_report):
|
|
with open(drc_report_path, "r") as txt:
|
|
if format_type == OutputReportType.JSON:
|
|
return json.loads(txt.read())
|
|
if format_type == OutputReportType.RPT:
|
|
return txt.read()
|
|
|
|
def process_bom(self, return_csv : bool = False) -> None:
|
|
sch_file_path = self.project_path / f"{self.project_name}.kicad_sch"
|
|
bom_output_path = Path(TEMP_FILE_PATH) / f"{self.project_name}{TEMP_DRC_REPORT_NAME}.csv"
|
|
subprocess.call(
|
|
f'{KICAD_CLI_PATH} sch export bom {sch_file_path} --output {bom_output_path}',
|
|
shell=True,
|
|
)
|
|
if (return_csv):
|
|
with open(bom_output_path, "r") as csvfile:
|
|
bom_csv = csv.reader(csvfile, delimiter=',', quotechar='"')
|
|
return [row for row in bom_csv]
|
|
|
|
def get_image(self,
|
|
image_type : str = "png",
|
|
height : int = 900,
|
|
width : int = 1600,
|
|
side : str = "top",
|
|
background : str = "default",
|
|
preset : str = "follow_pcb_editor",
|
|
zoom : int = 2,
|
|
) -> None:
|
|
"""
|
|
image_typ = "png" | "jpg"
|
|
side = "top" | "bottom" | "left" | "right" | "front" | "back"
|
|
background = "default" | "transparent" | "opaque"
|
|
"""
|
|
pcb_file_path = self.project_path / f"{self.project_name}.kicad_pcb"
|
|
render_output_path = Path(PCB_IMAGE_OUTPUT_PATH) / f"{self.project_name}_render.{image_type}"
|
|
subprocess.call(
|
|
f'{KICAD_CLI_PATH} pcb render {pcb_file_path} --output {render_output_path} --preset {preset} --zoom {zoom} ',
|
|
shell=True,
|
|
)
|
|
|
|
# look i dont know what you want to do
|
|
# but here you go
|
|
def create_3d_model(self) -> None:
|
|
...
|
|
|
|
# i am not giving you the pdf to output if you want to do that yourself go ahead
|
|
def create_schmatic_pdf(self) -> None:
|
|
sch_file_path = self.project_path / f"{self.project_name}.kicad_sch"
|
|
sch_report_path = Path(SCHEMATIC_OUTPUT_PATH) / f"{self.project_name}{SCHEMATIC_FILE_SUFFIX}.pdf"
|
|
subprocess.call(
|
|
f'{KICAD_CLI_PATH} sch export pdf {sch_file_path} --output {sch_report_path}',
|
|
shell=True,
|
|
)
|
|
|
|
def create_pcb_pdf(self, layers : list[str] = ["F.Cu", "B.Cu"]) -> None:
|
|
pcb_file_path = self.project_path / f"{self.project_name}.kicad_pcb"
|
|
pcb_report_path = Path(PCB_PDF_OUTPUT_PATH) / f"{self.project_name}{PCB_PDF_FILE_SUFFIX}.pdf"
|
|
subprocess.call(
|
|
f'{KICAD_CLI_PATH} pcb export pdf {pcb_file_path} --output {pcb_report_path} --layers {",".join(layers)}',
|
|
shell=True,
|
|
)
|
|
|
|
def export_pcb(self) -> None:
|
|
...
|
|
|
|
def download_datasheets(self) -> None:
|
|
...
|
|
|
|
|
|
class Report:
|
|
|
|
def export() -> str:
|
|
...
|
|
|
|
def main() -> None:
|
|
|
|
# find all kicad project files to operate on
|
|
for path in Path(".").rglob('*.kicad_pro'):
|
|
print(path.name)
|
|
print(path)
|
|
print(type(path.parent))
|
|
k = KicadProject(path)
|
|
k.drc_check()
|
|
print(k.erc_check(return_report=True))
|
|
print(k.process_bom(return_csv=True))
|
|
k.create_schmatic_pdf()
|
|
k.create_pcb_pdf()
|
|
k.get_image()
|
|
|
|
|
|
|
|
|
|
print("hello world");
|
|
|
|
if __name__ == "__main__":
|
|
main() |