diff --git a/README.md b/README.md index e0ead7e..9545448 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,260 @@ -# psychogenic-eeschema -eeschema schematic manipulation +# kicad skip: S-expression kicad file python parser + +Copyright © 2024 Pat Deegan, [psychogenic.com](https://psychogenic.com/) + + +This library is focused on scripted manipulations of schematics (and other) kicad _source_ _files_ +and allows any item to be edited in a hopefully intuitive way. + +It also provides helpers for common operations. + + +Kicad schematic, layout and other files are stored as trees of s-expressions, like + +``` +(kicad_sch (version 20230121) (generator eeschema) + (uuid 20adca1d-43a1-4784-9682-8b7dd1c7d330) + (title_block (title "My Demo Board") (date "2024-01-31") (rev "1.0.5") + (company "Psychogenic Technologies") (comment 1 "(C) 2023, 2024 Pat Deegan") + ) + (lib_symbols + (symbol "74xx:74CBTLV3257" (in_bom yes) (on_board yes) + (property "Reference" "U" (at 17.78 1.27 0) (effects (font (size 1.27 1.27)))) + (property "Value" "74CBTLV3257" (at 15.24 -1.27 0)(effects (font (size 1.27 1.27)))) + ... + (symbol (lib_id "SomeLib:Partname") (at 317.5 45.72 0) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid 342c76f3-b2b8-40b2-a0b0-d83e480188cc) + (property "Reference" "J4" (at 311.15 29.21 0)(effects (font (size 1.27 1.27)))) + (property "Value" "TT04_BREAKOUT_REVB" (at 317.5 76.2 0) (effects (font (size 1.27 1.27)))) + (property "Footprint" "TinyTapeout:TT04_BREAKOUT_SMB" (at 320.04 81.28 0) + (effects (font (size 1.27 1.27)) hide)) + (pin "A1" (uuid 5132b98d-ec39-4a2b-974d-c4d323ea43eb)) + (pin "A10" (uuid bf1f9b27-0b93-4778-ac69-684e16bea09c)) + (pin "A19" (uuid 43e3e4f6-008a-4ddf-a427-4414db85dcbb)) + ... +``` +which are great for machine parsing, but not so much for a quick scripted manipulation. + +With skip, you can quickly explore and modify the contents of a schematic (or, really, any +kicad s-expression file). + + +## Examples + +Effort has been made to make exploring the contents easy. This means: + +#### named attributes +Where possible, collections have named attributes: **do use** TAB-completion, schem. etc + +Examples + +``` +>>> schem.symbol.U TAB TAB +``` +outputs (something like, depending on schematic): + +``` + schem.symbol.U1 schem.symbol.U3 schem.symbol.U4_B schem.symbol.U4_D + schem.symbol.U2 schem.symbol.U4_A schem.symbol.U4_C schem.symbol.U4_E +``` + +and + +``` +>>> schem.symbol.U1.property. TAB TAB +``` + +outputs + +``` + schem.symbol.U1.property.Characteristics + schem.symbol.U1.property.Datasheet + schem.symbol.U1.property.DigikeyPN + schem.symbol.U1.property.Footprint + schem.symbol.U1.property.MPN + schem.symbol.U1.property.Reference + schem.symbol.U1.property.Value +``` + +#### representation +`__repr__` and `__str__` overrides so you have an idea what you're looking at. Just enter the variable in the REPL console and it should spit something sane out. + + +``` +>>> schem + + +>>> schem.symbol[23] + + +>>> schem.symbol[23].property +, , + , + , , + , , + , + ]> + +>>> schem.wire[22] + + +>>> schem.text[4] + + +# and much more, e.g. for library symbols, junctions, labels, whatever's in there +``` + + +## Quick walkthrough + +Here's some sample interaction with the library. The basic functions allow you to view and edit attributes. More involved helpers let you search and crawl the schematic to find things. + + +#### basic + +``` +# load a schematic +schem = skip.Schematic('samp/my_schem.kicad_sch') + +# loop over all components, treat collection as array +for component in schem.symbol: + component # do something + +# search through the symbols by reference or value, using regex or starts_with +>>> schem.symbol.reference_matches(r'(C|R)2[158]') +[, , , , , ] + +>>> sorted(schem.symbol.value_startswith('10k')) +[, , , , , , + , , , , , , + , ] + +# or refer to components by name +conn = schem.symbol.J15 + +# symbols have attributes +if not conn.in_bom: + conn.dnp = True + +# and properties (things that can be named by user) +for p in conn.property: + print(f'{p.name} = {p.value}') +# will output "Reference = J15", "MPN = USB4500-03-0-A" etc + +# and change properties, of course +>>> conn.property.MPN.value = 'ABC123' +>>> conn.property.MPN + + + + +# clone pretty much anything and modify it +>>> mpn_alt = conn.property.MPN.clone() +>>> mpn_alt.name = 'MPN_ALT' +>>> mpn_alt.value = 'ABC456' + + +# save the result +>>> schem.write('/tmp/newfile.kicad_sch') + +# let's verify the change +>>> schem.read('/tmp/newfile.kicad_sch') +>>> conn = schem.symbol.J15 +>>> for p in conn.property: + p + + + + + +``` + + +### Helpers + +Collections, and the source file object, have helpers to locate relevant elements. + +#### Attached elements + +Where applicable, such as for symbols (components), directly attached elements (via wires) +may be listed using attached_* + +``` +>>> conn = sch.symbol.J15 + +>>> conn.attached_ TAB TAB + conn.attached_all + conn.attached_global_labels + conn.attached_labels + conn.attached_symbols + conn.attached_wires +>>> conn.attached_symbols + [, , , + , , , + ] + +>>> conn.attached_labels + [