Blame view

BOm/bom_csv_grouped_extra.py 3.66 KB
f8ffc2c5   mahmoudrabia   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  #
  # Example python script to generate a BOM from a KiCad generic netlist
  #
  # Example: Sorted and Grouped CSV BOM
  #
  
  """
      @package
      Output: CSV (comma-separated)
      Grouped By: Value, Footprint, DNP, specified extra fields
      Sorted By: Reference
      Fields: #, Reference, Qty, Value, Footprint, DNP, specified extra fields
  
      Outputs components grouped by Value, Footprint, and specified extra fields.
      Extra fields can be passed as command line arguments at the end, one field per argument.
  
      Command line:
      python "pathToFile/bom_csv_grouped_extra.py" "%I" "%O.csv" "Extra_Field1" "Extra_Field2"
  """
  
  # Import the KiCad python helper module and the csv formatter
  import kicad_netlist_reader
  import kicad_utils
  import csv
  import sys
  
  # Get extra fields from the command line
  extra_fields = sys.argv[3:]
  
  comp_fields = ['Value', 'Footprint', 'DNP'] + extra_fields
  header_names = ['#', 'Reference', 'Qty'] + comp_fields
  
  def getComponentString(comp, field_name):
      if field_name == "Value":
          return comp.getValue()
      elif field_name == "Footprint":
          return comp.getFootprint()
      elif field_name == "DNP":
          return comp.getDNPString()
      elif field_name == "Datasheet":
          return comp.getDatasheet()
      else:
          return comp.getField( field_name )
  
  def myEqu(self, other):
      """myEqu is a more advanced equivalence function for components which is
      used by component grouping. Normal operation is to group components based
      on their Value and Footprint.
  
      In this example of a more advanced equivalency operator we also compare the
      Footprint, Value, DNP and all extra fields passed from the command line. If
      these fields are not used in some parts they will simply be ignored (they
      will match as both will be empty strings).
  
      """
      result = True
      for field_name in comp_fields:
          if getComponentString(self, field_name) != getComponentString(other, field_name):
              result = False
  
      return result
  
  # Override the component equivalence operator - it is important to do this
  # before loading the netlist, otherwise all components will have the original
  # equivalency operator.
  kicad_netlist_reader.comp.__eq__ = myEqu
  
  # Generate an instance of a generic netlist, and load the netlist tree from
  # the command line option. If the file doesn't exist, execution will stop
  net = kicad_netlist_reader.netlist(sys.argv[1])
  
  # Open a file to write to, if the file cannot be opened output to stdout
  # instead
  try:
      f = kicad_utils.open_file_writeUTF8(sys.argv[2], 'w')
  except IOError:
      e = "Can't open output file for writing: " + sys.argv[2]
      print(__file__, ":", e, sys.stderr)
      f = sys.stdout
  
  # Create a new csv writer object to use as the output formatter
  out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=csv.QUOTE_ALL)
  
  # Output a CSV header
  out.writerow(header_names)
  
  # Get all of the components in groups of matching parts + values
  # (see kicad_netlist_reader.py)
  grouped = net.groupComponents()
  
  # Output all of the component information
  index = 1
  for group in grouped:
      refs = ""
  
      # Add the reference of every component in the group and keep a reference
      # to the component so that the other data can be filled in once per group
      for component in group:
          refs += component.getRef() + ", "
          c = component
  
      # Remove trailing comma
      refs = refs[:-2]
  
      # Fill in the component groups common data
      row = []
      row.append( index )
      row.append( refs )
      row.append( len(group) )
  
      # Add the values of component-specific data
      for field_name in comp_fields:
          row.append( getComponentString( c, field_name ) )
  
      out.writerow(row)
  
      index += 1