Files
kicad-project-template-acti…/.hooks/main.py
2025-12-31 02:25:00 +13:00

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()