KiCAD Scripting - MD
KiCAD Scripting - MD
## Introduction
KiCad uses an s-expression file format for symbol libraries, footprint libraries,
schematics, printed circuit boards, and title block and border worksheets.
### Syntax
* Syntax is based on the Specctra DSN file format.
* Token definitions are delimited by opening `(` and closing `)` parenthesis.
* All tokens are lowercase.
* Tokens cannot contain any white space characters or special characters other
than the underscore '_' character.
* All strings are quoted using the double quote character (") and are UTF-8
encoded.
* Tokens can have zero or more attributes.
* Human readability is a design goal.
### Conventions
In order to use the file format documentation properly, there are a few notation
conventions that must be understood.
* Token attributes are upper case descriptive names. For example `(at X Y)`, X is
the horizontal coordinate and Y is the vertical coordinate.
* Some tokens have a limited number of possible attribute values which are
separated by a logical or character '|'. For example `(visible yes|no)` the only
valid attributes for the `visible` token are `yes` or `no`.
* Some tokens have optional attributes which are enclosed in square braces. For
example `(paper A0 [portrait])` the page portrait setting is optional.
## Common Syntax
This section defines all syntax that is shared across the symbol library, footprint
library, schematic, board, and work sheet file formats.
> **Note**
> The "LIBRARY_NICKNAME" is not stored in the library files because a library
cannot know what the assigned library table nickname is in advance. Only the
"ENTRY_NAME" is saved in the library files.
```
(at
X (1)
Y (2)
[ANGLE] (3)
)
```
1. **X**: The X attribute defines the horizontal position of the object.
2. **Y**: The Y attribute defines the vertical position of the object.
3. **ANGLE**: The optional ANGLE attribute defines the rotational angle of the
object. Not all objects have rotational position definitions.
> **Note**
> Symbol `text` ANGLEs are stored in tenth’s of a degree. All other ANGLEs are
stored in degrees.
### Images
The `image` token defines an embedded image. This section will not exist if no
images are present.
```
(image
POSITION_IDENTIFIER (1)
[(scale SCALAR)] (2)
[(layer LAYER_DEFINITIONS)] (3)
UNIQUE_IDENTIFIER (4)
(data IMAGE_DATA) (5)
)
```
1. **POSITION_IDENTIFIER**: Defines the X and Y coordinates of the image.
2. **scale**: The optional `scale` token attribute defines the SCALE_FACTOR of the
image.
3. **layer**: The `layer` token attribute defines the associated board layer of
the image using one canonical layer name. Only used by board and footprint images.
4. **UNIQUE_IDENTIFIER**: Defines the universally unique identifier for the image.
5. **data**: The `data` token attribute defines the image data in the portable
network graphics format (PNG) encoded with MIME type base64.
## Board Coordinates
* The minimum internal unit for printed circuit board and footprint files is one
nanometer so there is maximum resolution of six decimal places or 0.000001 mm. Any
precision beyond six places will be truncated.
## Layers
All drawable board and footprint objects exist on a `layer` which is defined in the
drawable item definition. All layers can be renamed by the user.
> **Note**
> Internally, all layer names are canonical. User defined layer names are only used
for display and output purposes.
```
(layer
LAYER_DEFINITION (1)
)
```
1. **LAYER_DEFINITION**: Layer definitions can be specified as a list of one or
more canonical layer names or with a '*' wildcard to represent all layers that
match the rest of the wildcard. For instance, `*.Cu` represents all of the copper
layers. This only applies to canonical layers names.
### Capacity
* 60 total layers.
* 32 copper layers.
* 8 paired technical layers for silk screen, solder mask, solder paste, and
adhesive.
* 4 user pre-defined layers for drawings, engineering change order (ECO), and
comments.
* 1 layer to define the board outline.
* 1 layer to define the board margins.
* 9 optional user definable layers.
### Footprint
The `footprint` token defines a footprint.
> **Note**
> Prior to version 6, the `footprint` token was referred to as `module`.
```
(footprint
["LIBRARY_LINK"] (1)
[locked] (2)
[placed] (3)
(layer LAYER_DEFINITIONS) (4)
(tedit TIME_STAMP) (5)
[(uuid UUID)] (6)
[POSITION_IDENTIFIER] (7)
[(descr "DESCRIPTION")] (8)
[(tags "NAME")] (9)
[(property "KEY" "VALUE") ...] (10)
(path "PATH") (11)
[(autoplace_cost90 COST)] (12)
[(autoplace_cost180 COST)] (13)
[(solder_mask_margin MARGIN)] (14)
[(solder_paste_margin MARGIN)] (15)
[(solder_paste_ratio RATIO)] (16)
[(clearance CLEARANCE)] (17)
[(zone_connect CONNECTION_TYPE)] (18)
[(thermal_width WIDTH)] (19)
[(thermal_gap DISTANCE)] (20)
[ATTRIBUTES] (21)
[(private_layers LAYER_DEFINITIONS)] (22)
[(net_tie_pad_groups PAD_GROUP_DEFINITIONS)] (23)
GRAPHIC_ITEMS... (24)
PADS... (25)
ZONES... (26)
GROUPS... (27)
3D_MODEL (28)
)
```
1. **"LIBRARY_LINK"**: Defines the link to footprint library of the footprint.
(Board file format only)
2. **locked**: Optional flag to indicate the footprint cannot be edited.
3. **placed**: Optional flag to indicate that the footprint has not been placed.
4. **layer**: Defines the canonical layer the footprint is placed on.
5. **tedit**: Defines the last time the footprint was edited.
6. **uuid**: Defines the unique identifier for the footprint. (Board file format
only)
7. **POSITION_IDENTIFIER**: Defines the X, Y coordinates and rotational angle.
(Board file format only)
8. **descr**: Optional string containing the description of the footprint.
9. **tags**: Optional string of search tags for the footprint.
10. **property**: Optional property for the footprint.
11. **path**: Defines the hierarchical path of the schematic symbol linked to the
footprint. (Board file format only)
12. **autoplace_cost90**: Defines the vertical cost (1-10) for the automatic
placement tool. (Board file format only)
13. **autoplace_cost180**: Defines the horizontal cost (1-10) for the automatic
placement tool. (Board file format only)
14. **solder_mask_margin**: Defines the solder mask distance from all pads in the
footprint.
15. **solder_paste_margin**: Defines the solder paste distance from all pads in the
footprint.
16. **solder_paste_ratio**: Defines the percentage of the pad size used for solder
paste.
17. **clearance**: Defines the clearance to all board copper objects for all pads
in the footprint.
18. **zone_connect**: Defines how all pads connect to a filled zone (0: no connect,
1: thermal reliefs, 2: solid fill).
19. **thermal_width**: Defines the thermal relief spoke width for zone connections.
20. **thermal_gap**: Defines the distance from the pad to the zone for thermal
relief connections.
21. **ATTRIBUTES**: Optional section defining the attributes of the footprint.
22. **private_layers**: Optional list of canonical layer names which are private to
the footprint.
23. **net_tie_pad_groups**: Optional list of net-tie pad groups.
24. **GRAPHIC_ITEMS**: List of one or more graphical objects in the footprint.
25. **PADS**: Optional list of pads in the footprint.
26. **ZONES**: Optional list of keep out zones in the footprint.
27. **GROUPS**: Optional list of grouped objects in the footprint.
28. **3D_MODEL**: Defines the 3D model object associated with the footprint.
---
# S-Expressions
Last Modified: 2024-04-28
```
sexpr ::= ( sx )
sx ::= atom sxtail | sexpr sxtail | NULL
sxtail ::= sx | NULL
atom :: quoted | value
quoted :: "ws_string"
value :: nws_string
```
The s-expression syntax used in Kicad uses two quoting/syntax strategies, given by
the needs of the Specctra DSN specification and of our own non-specctra needs. The
Specctra DSN specification is not very clear with regard to quoting and on top of
that there is Freerouter’s interpretation, which would actually supercede anything
in the Specctra DSN spec anyway, due to a desire to be compatible with Freerouter.
We have our own needs, which go beyond those of the Specctra DSN spec, so we
support the two syntaxes or quoting protocols for quoted atoms:
We can control our own destiny better by having a separately defined mode for non
Specctra DSN files.
There needs to be agreement between how a file is saved, and how a file is read
back in, in either mode, to fulfill the round-tripping requirements. A file written
using one mode may not necessarily be readable using the other mode, although it
might be. Just don’t count on it.
In Kicad mode:
The decision to wrap the string or not is left to the `Quoted()` function. If the
string is wrapped, it will also escape internal double quotes, \n’s and \r’s. Any
null string is wrapped in quotes, and so is any string which starts with '#', so
that it is not confused with an s-expression comment.
---
# Schematic File Format
Last Modified: 2024-04-28
## Introduction
This documents the s-expression schematic file format for all versions of KiCad
from 6.0.
* Schematic files use the `.kicad_sch` extension.
## Layout
A schematic file includes the following sections:
* Header
* Unique Identifier
* Page Settings
* Title Block Section
* Symbol Library Symbol Definition
* Junction Section
* No Connect Section
* Wire and Bus Section
* Image Section
* Graphical Line Section
* Graphical Text Section
* Local Label Section
* Global Label Section
* Symbol Section
* Hierarchical Sheet Section
* Root Sheet Instance Section
## Header Section
The `kicad_sch` token indicates that it is KiCad schematic file. This section is
required.
> **Note**
> Third party scripts should not use `eeschema` as the generator identifier. Please
use some other identifier so that bugs introduced by third party generators are not
confused with a schematic file created by KiCad.
```
(kicad_sch
(version VERSION) (1)
(generator GENERATOR) (2)
## Symbol Section
The `symbol` token in the symbol section of the schematic defines an instance of a
symbol from the library symbol section of the schematic.
```
(symbol
"LIBRARY_IDENTIFIER" (1)
POSITION_IDENTIFIER (2)
(unit UNIT) (3)
(in_bom yes|no) (4)
(on_board yes|no) (5)
UNIQUE_IDENTIFIER (6)
PROPERTIES (7)
(pin "1" (uuid e148648c-6605-4af1-832a-31eaf808c2f8)) (8)
(instances (9)
(project "PROJECT_NAME" (10)
(path "PATH_INSTANCE" (11)
(reference "REFERENCE") (12)
(unit UNIT) (13)
)
...
)
...
)
)
```
1. **LIBRARY_IDENTIFIER**: Defines which symbol in the library symbol section is
referenced.
2. **POSITION_IDENTIFIER**: Defines the X, Y coordinates and angle of rotation of
the symbol.
3. **unit**: Defines which unit in the symbol library definition is represented.
4. **in_bom**: Determines if the symbol appears in the bill of materials.
5. **on_board**: Determines if the footprint is exported to the board.
6. **UNIQUE_IDENTIFIER**: The universally unique identifier for the symbol
instance.
7. **PROPERTIES**: A list of symbol properties.
8. **pin**: Defines pin UUID mapping.
9. **instances**: A list of symbol instances grouped by project.
10. **project**: Defines the project name for the instance data.
11. **path**: The path to the sheet instance for the instance data.
12. **reference**: The reference designator for the symbol instance.
13. **unit**: The symbol unit for the symbol instance.
---
# Symbol Library File Format
Last Modified: 2024-04-28
## Introduction
This documents the s-expression symbol library file format for all versions of
KiCad from 6.0.
## Layout
A symbol library file includes the following sections:
* Header
* Symbol Definition
## Header Section
The `kicad_symbol_lib` token indicates that it is KiCad symbol library file. This
section is required.
> **Note**
> Third party scripts should not use `kicad_symbol_editor` as the generator
identifier. Please use some other identifier so that bugs introduced by third party
generators are not confused with a footprint library file created by KiCad.
```
(kicad_symbol_lib
(version VERSION) (1)
(generator GENERATOR) (2)
## Symbol Section
The `symbol` token defines a symbol in the library.
```
[SYMBOL_DEFINITION] (1)
...
```
1. **SYMBOL_DEFINITION**: The `SYMBOL_DEFINITION` defines the symbol(s) in the
library file.
The structure consists of an outer `symbol` block containing metadata and at least
one **nested** `symbol` block that defines the actual graphics and pins.
```sexp
(symbol "SYMBOL_NAME"
;; Properties defining the logical component
(property "Reference" "U" ...)
(property "Value" "SYMBOL_NAME" ...)
(in_bom yes|no)
(on_board yes|no)
...
;; Nested block for graphical representation and pins for Unit 1, Style 1
(symbol "SYMBOL_NAME_1_1"
;; Graphical items (lines, rectangles, etc.) are inside this nested block
(rectangle (start -10.16 -5.08) (end 10.16 5.08)
(stroke (width 0.254) (type default))
(fill (type none))
)
> **Warning**
> A common parsing error is to only read the direct children of the top-level
`symbol` block. This will fail to find any pin definitions or graphical shapes.
Parsers **must** iterate into the nested `symbol` block(s) (e.g.,
`"SYMBOL_NAME_1_1"`) to extract electrically relevant pin data and drawing
information.
---
### Interacting with the KiCad CLI
While direct parsing of s-expression files provides the most granular access to
KiCad data, a more straightforward method for certain tasks is to use the `kicad-
cli` executable. This command-line interface is a powerful tool for automating
processes and is ideal for extracting high-level, electrically-relevant information
like netlists and component bills of materials (BOMs) without needing to implement
complex parsing logic.
You can interface with `kicad-cli` from Python using the built-in `subprocess`
module.
```python
import subprocess
import os
from pathlib import Path
Args:
command_args: A list of strings representing the command and its arguments.
timeout_seconds: How long to wait for the command to complete.
Returns:
A tuple of (success, stdout, stderr).
'''
command = [KICAD_CLI_PATH] + command_args
try:
print(f"Running command: {' '.join(command)}")
result = subprocess.run(
command,
check=True, # Raise CalledProcessError for non-zero exit codes
capture_output=True, # Capture stdout and stderr
text=True, # Decode stdout/stderr as text
timeout=timeout_seconds
)
return (True, result.stdout, result.stderr)
except FileNotFoundError:
print(f"ERROR: '{KICAD_CLI_PATH}' not found.")
print("Please ensure the KiCad CLI is in your PATH or set KICAD_CLI_PATH.")
return (False, "", "kicad-cli not found")
except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as e:
print(f"ERROR: KiCad CLI command failed: {e}")
stdout = e.stdout if hasattr(e, 'stdout') else ""
stderr = e.stderr if hasattr(e, 'stderr') else ""
return (False, stdout, stderr)
```
**Example:**
```python
def export_netlist(sch_file: Path):
netlist_file = sch_file.with_suffix('.net')
args = [
"sch", "export", "netlist",
"--format", "orcadpcb2",
"--output", str(netlist_file),
str(sch_file)
]
success, _, stderr = run_kicad_cli(args)
if success:
print(f"Successfully exported netlist to {netlist_file}")
with open(netlist_file, 'r') as f:
# You can now process the netlist content
netlist_content = f.read()
# print(netlist_content[:200]) # Print first 200 chars
else:
print(f"Failed to export netlist. Stderr: {stderr}")
# Usage:
# my_schematic = Path("path/to/your/project/schematic.kicad_sch")
# export_netlist(my_schematic)
```
A BOM lists all components in a design. This is crucial for understanding the
electrical system's parts.
**Example:**
```python
def export_bom(sch_file: Path):
bom_file = sch_file.with_suffix('.csv')
args = [
"sch", "export", "bom",
"--output", str(bom_file),
"--fields", "Reference,Value,Footprint,Datasheet,${QUANTITY},${DNP}",
"--labels", "Reference,Value,Footprint,Datasheet,Qty,DNP",
"--group-by", "Value,Footprint",
"--exclude-dnp",
str(sch_file)
]
success, _, stderr = run_kicad_cli(args)
if success:
print(f"Successfully exported BOM to {bom_file}")
else:
print(f"Failed to export BOM. Stderr: {stderr}")
```
This command generates an intermediate XML file which can then be processed by
external scripts.
**Example:**
```python
def export_legacy_bom(sch_file: Path):
xml_bom_file = sch_file.with_name(f"{sch_file.stem}-bom.xml")
args = [
"sch", "export", "python-bom",
"--output", str(xml_bom_file),
str(sch_file)
]
success, _, stderr = run_kicad_cli(args)
if success:
print(f"Successfully exported legacy XML BOM to {xml_bom_file}")
else:
print(f"Failed to export legacy BOM. Stderr: {stderr}")
```
Position files (`.pos`) list the location, rotation, and side for each component on
the PCB.
* **Key Options:**
* `--format <format>`: `ascii`, `csv` (recommended for parsing), or `gerber`.
* `--units <unit>`: `mm` or `in`.
* `--side <side>`: `front`, `back`, or `both`.
**Example:**
```python
def export_position_file(pcb_file: Path):
pos_file = pcb_file.with_suffix('.csv')
args = [
"pcb", "export", "pos",
"--output", str(pos_file),
"--format", "csv",
"--units", "mm",
str(pcb_file)
]
success, _, stderr = run_kicad_cli(args)
if success:
print(f"Successfully exported position file to {pos_file}")
else:
print(f"Failed to export position file. Stderr: {stderr}")
```
For more comprehensive data sets that include board layers, stackup, nets, and
components in a single file, the IPC-2581 and Gencad formats are useful. These are
standardized formats for exchanging data with other EDA and manufacturing tools.
This command generates a single `.xml` file containing a rich description of the
board.
**Example:**
```python
def export_ipc2581(pcb_file: Path):
ipc_file = pcb_file.with_suffix('.xml')
args = [
"pcb", "export", "ipc2581",
"--output", str(ipc_file),
# Optional: set IPC-2581 version, units, compression, etc.
"--version", "C",
"--units", "mm",
"--compress",
str(pcb_file)
]
success, _, stderr = run_kicad_cli(args)
if success:
print(f"Successfully exported IPC-2581 file to {ipc_file}")
else:
print(f"Failed to export IPC-2581 file. Stderr: {stderr}")
```