Below is a script that exports a pcbnew formatted NETLIST from a design file.
Useful for manual/text originated designs, or designs imported from other CAD flows, where you may not have an Original NETLIST, or may be unsure about its validity.
# PcbNew_Export_PcbNew_NET derived from PcbNew_Export_PADS_NET.py
# eg Usage - in KiCad PcbNew Python Console paste after >>>
# >>> execfile("C:\KiCad_Python\Check_Footprint_Attr\PcbNew_Export_PcbNew_NET.py") - gone in P3 ?
#
# Purposes :
# * for "complete the circle" tests when using KiCad IMPORT design feature
# * for ECO check, create a NET copy when starting, and confirm matches when completed.
# * for Version control reporting of merged, or non SCH design flows.
# V1.0 first port from PcbNew_Export_PADS_NET.py
# checked can import original, and the exported netlists fine, and can import-over.
# Notice the NET number jumps around, so original does not match exported, but the netname seems to win, so import is ok.
# That means you should save an exported COPY asap, if you want to keep an audit comparison.
#
# V1.01 Added report comment at end of net file, KiCad seems to tolerate that
# V1.02 Improved tests and reports
# V1.03 Fixed message Info: Changing component path "X1:/568E18BC" to "", by adding extract of needed (sheetpath (tstamps /)) (tstamp 568E18BC) lines
import string # used for rsplit
import pcbnew # ok on fresh start
pcb = pcbnew.GetBoard() # Works on Loaded Design file
# For now, just dump the ASCII NET info to the Python Console, can add File-name later
# Allows comments as *REMARK*
print '(export (version D)'
print ' (components'
#(export (version D)
# (components
# (comp (ref J1)
# (value TI_BOOSTER_40_J1)
# (footprint Pin_Headers:Pin_Header_Angled_1x10_Pitch2.54mm))
# (comp (ref J2)
# ~~~~~~~~~~~~~~ Audit counters ~~~~~~~~~~~~~~~~~
ShtPathCount = 0
PartCount = 0
SkipCount = 0
PinCount = 0
Warnings = 0
# def GetPadCount(self, *args): """ GetPadCount(MODULE self, INCLUDE_NPTH_T aIncludeNPTH) -> unsigned int GetPadCount(MODULE self) -> unsigned int """ return _pcbnew.MODULE_GetPadCount(self, *args)
# def GetUniquePadCount(self, *args): """ GetUniquePadCount(MODULE self, INCLUDE_NPTH_T aIncludeNPTH) -> unsigned int GetUniquePadCount(MODULE self) -> unsigned int """ return _pcbnew.MODULE_GetUniquePadCount(self, *args)
# (comp (ref J1)
# (value TI_BOOSTER_40_J1)
# (footprint Pin_Headers:Pin_Header_Angled_1x10_Pitch2.54mm))
# (comp (ref J2)
# try to export (path /568E18BC) entry - similar to (attr smd) called Sheet path in help, hover says it is an A unique ID, a timestamp, alternate identifier to the reference.
# part.GetTimeStamp() gives 1448919751 = 0x565CC2C7
# Last item JP1 has /567C1358 seems quite close to .. 0x567C132C 0x567C1358-1450971948 = 44 WTF ? 1450971948 = 0x567C132C (tstamp 567C132C)
# (module hack-footprints:SMD_Jumper (layer B.Cu) (tedit 569F9EC7) (tstamp 567C132C)
# (path /567C1358) << want this one, NOT tstamp ??, tho tstamp is close usually quite close ? aGetPath /567C1358
# P6 gives 0x569F8542-1453287917 = 6997 1453287917 = 0x569F69ED (tstamp 569F69ED)
# P5 gives 0x569F6050-1453284133 = 1323 1453284133 = 0x569F5B25 (tstamp 569F5B25)
for part in pcb.GetModules():
ref = part.Reference().GetText()
if ref: # skip empty names - PCAD files seem to have some ?
# footprint = part.GetFPID().GetFootprintName() fails v5rc 2018 ?, can't see GetFootprintName in helps ?
footprint = part.GetFPID().GetLibItemName() # seems to fix that ?
val = part.Value().GetText()
LibNick = part.GetFPID().GetLibNickname() # This is UTF8, but how to check if printing nothing ??
aGetPath = part.GetPath() # Gets string from FootprintProperties.SheetPath, can have Number AND prefix like /567C1359
print ' (comp (ref "%s")'%(ref)
print ' (value "%s")'%(val)
if aGetPath <> '' : # make this optional ? gives error messages if not in netlist
aPtn = aGetPath.rpartition('/') # Guess paths always use / ?
if aPtn[1] <> '' :
print ' (sheetpath (tstamps %s%s))'%(aPtn[0],aPtn[1])
print ' (tstamp %s)'%(aPtn[2])
ShtPathCount = ShtPathCount + 1
if not LibNick.empty() :
print ' (footprint "%s:%s"))'%(LibNick,footprint)
else: #empty string in library, so shorter format
print ' (footprint "%s"))'%(footprint)
PartCount = PartCount + 1
else:
SkipCount = SkipCount + 1
print ')' # Balance braces
Nc = pcb.GetNetCount()
Pc = pcb.GetPadCount()
print " (nets" # Start NETS section
# (net (code 6) (name /NTH)
# (node (ref J1) (pin 9))
# (node (ref TH1) (pin 2)))
# (net (code 7) (name "Net-(J1-Pad3)") << hmm, some use quotes, some do not ??
#
for sN in range(1,Nc): # order does not seem to match .kicad_pcb node numbers, but maybe does not matter ?
Net = pcb.FindNet(sN) # Scan by node number -> NETINFO_ITEM
nName = Net.GetNetname()
# if '-' in nName: # Do Other chars need "" ? - does it matter if "" are on a std NET? - seems not, so can simplify with "" everywhere.
print ' (net (code %s) (name "%s")'%(sN,nName) # Place all netnames in quotes
# else:
# print ' (net (code %s) (name "%s")'%(sN,nName)
# for pad in Net.Pads(): # WTF fails May 2018 V5 RC ?? 'NETINFO_ITEM' object has no attribute 'Pads' ?
# print pad.GetPadName() # MISSING IN v5.X?
for pad in pcb.GetPads(): # will be MUCH slower, but seems to fix it....
if (pad.GetNetCode() == sN): # Net code may be faster ?
PinName = pad.GetPadName()
Module = pad.GetParent()
RefDes = Module.GetReference()
PinCount = PinCount+1
print ' (node (ref "%s") (pin "%s"))'%(RefDes,PinName) # try quotes to see if empty pinnum and ref helped
print ')' # Balance braces
print '))' # Balance braces
print '#Comment KiCad NET export using PcbNew_Export_PcbNew_NET.py v1.03, from Kicad design: %s'%(pcb.GetFileName())
print "#Comment: Parts:%s, Nets:%s, PinsConected:%s, TotalPads:%s, Ref Skipped:%s, SheetPath:%s" %(PartCount,(Nc-1),PinCount,Pc,SkipCount,ShtPathCount) # Kicad tolerates EOF comment line, so report
# Test Results Good, - when Part-only
# example:
#Comment KiCad NET export using PcbNew_Export_PcbNew_NET.py v1.02, from Kicad design: C:/KiCadFiles/HACKmaster/HACK-master-R3/kicad/hack_jg.kicad_pcb
#Comment: Parts:36, Nets:44, PinsConected:164, TotalPads:169, Ref Skipped:0
# references :
# https://github.com/KiCad/kicad-doc/blob/master/src/pcbnew/pcbnew_python_scripting.adoc
# C:\Program Files\KiCad\lib\python2.7\site-packages\pcbnew.py
# Test operation/reports :
# Import New with new node gives
# Changing footprint "U1:" pad "G" net name from "" to "GND".
# import with node removed
# Clearing component "U1:" pin "G" net name.