diff --git a/.v5_sch/add_part_number.py b/.v5_sch/add_part_number.py deleted file mode 100755 index b0d1387a..00000000 --- a/.v5_sch/add_part_number.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from __future__ import print_function -from sch import * -import argparse -import csv, sys - -parser = argparse.ArgumentParser() -parser.add_argument('sch_file', nargs='+') -parser.add_argument('--bom-csv', help='a BOM csv file that will be used to fill the PN field', action='store') -parser.add_argument('--bom-ref-field', help='defines the reference field name in the BOM', action='store', default='Reference(s)') -parser.add_argument('--bom-pn-field', help='defines the part number field name in the BOM', action='store', default='MPN') -parser.add_argument('--pn-field-name', help='defines the part number field name that will be used in the sch files', action='store', default='MPN') -args = parser.parse_args() -bom = [] - -if args.bom_csv: - f = open(args.bom_csv, 'r') - reader = csv.reader(f) - header_ok = False - for row in reader: - # Try to locate the header row - if args.bom_ref_field in row and args.bom_pn_field in row: - header_ok = True - ref_col = row.index(args.bom_ref_field) - pn_col = row.index(args.bom_pn_field) - - elif header_ok: - bom.append(row) - - if not header_ok: - sys.stderr.write('Cannot find a header with one or both fields: "%s", "%s"\n' % (args.bom_ref_field, args.bom_pn_field)) - sys.exit() - -for f in args.sch_file: - sch = Schematic(f) - - for component in sch.components: - # check if is power related component - if '#PWR' in component.fields[0]['ref'] or\ - 'PWR_FLAG' in component.fields[1]['ref']: - continue - - # create or get the PN field - for field in component.fields: - if field['name'].replace('"', '') == args.pn_field_name: - break - else: - field = component.addField(name="{}".format(args.pn_field_name), - ref="{}".format("~")) - - # component reference - comp_ref = component.fields[0]['ref'].replace('"', '') - - # search the component in the BOM items and get the PN - for item in bom: - item_refs = item[ref_col].replace(' ', '').split(',') - if item[pn_col] and comp_ref in item_refs: - field['ref'] = '"' + item[pn_col] + '"' - break - - sch.save() diff --git a/.v5_sch/sch.py b/.v5_sch/sch.py deleted file mode 100644 index 8cfb50b6..00000000 --- a/.v5_sch/sch.py +++ /dev/null @@ -1,329 +0,0 @@ -# -*- coding: utf-8 -*- - -import sys -import shlex -import re - - -def ensure_quoted(s): - """ - Returns a quoted version of string 's' if that's not already the case - """ - rx = r"^\"(.+)\"$" - - if re.match(rx, s) is not None: - return s - else: - return "\"{}\"".format(s) - - -class Description(object): - """ - A class to parse description information of Schematic Files Format of the KiCad - TODO: Need to be done, currently just stores the raw data read from file - """ - def __init__(self, data): - self.raw_data = data - - -class Component(object): - """ - A class to parse components of Schematic Files Format of the KiCad - """ - _L_KEYS = ['name', 'ref'] - _U_KEYS = ['unit', 'convert', 'time_stamp'] - _P_KEYS = ['posx', 'posy'] - _AR_KEYS = ['path', 'ref', 'part'] - _F_KEYS = ['id', 'ref', 'orient', 'posx', 'posy', 'size', 'attributs', - 'hjust', 'props', 'name'] - - _KEYS = {'L': _L_KEYS, 'U': _U_KEYS, 'P': _P_KEYS, - 'AR': _AR_KEYS, 'F': _F_KEYS} - - def __init__(self, data): - self.labels = {} - self.unit = {} - self.position = {} - self.references = [] - self.fields = [] - self.old_stuff = [] - - for line in data: - if line[0] == '\t': - self.old_stuff.append(line) - continue - - line = line.replace('\n', '') - s = shlex.shlex(line) - s.whitespace_split = True - s.commenters = '' - s.quotes = '"' - line = list(s) - - # select the keys list and default values array - if line[0] in self._KEYS: - key_list = self._KEYS[line[0]] - values = line[1:] + ['']*(len(key_list) - len(line[1:])) - - if line[0] == 'L': - self.labels = dict(zip(key_list, values)) - elif line[0] == 'U': - self.unit = dict(zip(key_list, values)) - elif line[0] == 'P': - self.position = dict(zip(key_list, values)) - elif line[0] == 'AR': - self.references.append(dict(zip(key_list, values))) - elif line[0] == 'F': - self.fields.append(dict(zip(key_list, values))) - - # TODO: enhancements - # * 'value' could be used instead of 'ref' - def addField(self, *, ref, name, **field_data): - field = {'id': None, 'ref': None, 'orient': 'H', 'posx': '0', - 'posy': '0', 'size': '50', 'attributs': '0001', - 'hjust': 'C', 'props': 'CNN', 'name': '~'} - - # 'ref' and 'name' must be quoted - ref = ensure_quoted(ref) - name = ensure_quoted(name) - - # ignore invalid items in field_data - field_data = {key: val for (key, val) in field_data.items() - if key in self._F_KEYS} - - # merge dictionaries and set the id value - field.update(field_data, ref=ref, name=name) - field['id'] = str(len(self.fields)) - - self.fields.append(field) - return field - - -class Sheet(object): - """ - A class to parse sheets of Schematic Files Format of the KiCad - """ - _S_KEYS = ['topLeftPosx', 'topLeftPosy', 'botRightPosx', 'botRightPosy'] - _U_KEYS = ['uniqID'] - _F_KEYS = ['id', 'value', 'IOState', 'side', 'posx', 'posy', 'size'] - - _KEYS = {'S': _S_KEYS, 'U': _U_KEYS, 'F': _F_KEYS} - - def __init__(self, data): - self.shape = {} - self.unit = {} - self.fields = [] - for line in data: - line = line.replace('\n', '') - s = shlex.shlex(line) - s.whitespace_split = True - s.commenters = '' - s.quotes = '"' - line = list(s) - # select the keys list and default values array - if line[0] in self._KEYS: - key_list = self._KEYS[line[0]] - values = line[1:] + ['']*(len(key_list) - len(line[1:])) - if line[0] == 'S': - self.shape = dict(zip(key_list, values)) - elif line[0] == 'U': - self.unit = dict(zip(key_list, values)) - elif line[0][0] == 'F': - key_list = self._F_KEYS - values = line + ['' for n in range(len(key_list) - len(line))] - self.fields.append(dict(zip(key_list, values))) - - -class Bitmap(object): - """ - A class to parse bitmaps of Schematic Files Format of the KiCad - TODO: Need to be done, currently just stores the raw data read from file - """ - def __init__(self, data): - self.raw_data = data - - -class Schematic(object): - """ - A class to parse Schematic Files Format of the KiCad - """ - def __init__(self, filename): - f = open(filename) - self.filename = filename - self.header = f.readline() - self.libs = [] - self.eelayer = None - self.description = None - self.components = [] - self.sheets = [] - self.bitmaps = [] - self.texts = [] - self.wires = [] - self.entries = [] - self.conns = [] - self.noconns = [] - - if 'EESchema Schematic File' not in self.header: - self.header = None - sys.stderr.write('The file is not a KiCad Schematic File\n') - return - - building_block = False - - while True: - line = f.readline() - if not line: - break - - if line.startswith('LIBS:'): - self.libs.append(line) - - elif line.startswith('EELAYER END'): - pass - elif line.startswith('EELAYER'): - self.eelayer = line - - elif not building_block: - if line.startswith('$'): - building_block = True - block_data = [] - block_data.append(line) - elif line.startswith('Text'): - data = {'desc': line, 'data': f.readline()} - self.texts.append(data) - elif line.startswith('Wire'): - data = {'desc': line, 'data': f.readline()} - self.wires.append(data) - elif line.startswith('Entry'): - data = {'desc': line, 'data': f.readline()} - self.entries.append(data) - elif line.startswith('Connection'): - data = {'desc': line} - self.conns.append(data) - elif line.startswith('NoConn'): - data = {'desc': line} - self.noconns.append(data) - - elif building_block: - block_data.append(line) - if line.startswith('$End'): - building_block = False - - if line.startswith('$EndDescr'): - self.description = Description(block_data) - if line.startswith('$EndComp'): - self.components.append(Component(block_data)) - if line.startswith('$EndSheet'): - self.sheets.append(Sheet(block_data)) - if line.startswith('$EndBitmap'): - self.bitmaps.append(Bitmap(block_data)) - - def save(self, filename=None): - # check whether it has header, what means that sch file was loaded fine - if not self.header: - return - - if not filename: - filename = self.filename - - # insert the header - to_write = [] - to_write += [self.header] - - # LIBS - to_write += self.libs - - # EELAYER - to_write += [self.eelayer, 'EELAYER END\n'] - - # Description - to_write += self.description.raw_data - - # Sheets - for sheet in self.sheets: - to_write += ['$Sheet\n'] - if sheet.shape: - line = 'S ' - for key in sheet._S_KEYS: - line += sheet.shape[key] + ' ' - to_write += [line.rstrip() + '\n'] - if sheet.unit: - line = 'U ' - for key in sheet._U_KEYS: - line += sheet.unit[key] + ' ' - to_write += [line.rstrip() + '\n'] - - for field in sheet.fields: - line = '' - for key in sheet._F_KEYS: - line += field[key] + ' ' - to_write += [line.rstrip() + '\n'] - to_write += ['$EndSheet\n'] - - # Components - for component in self.components: - to_write += ['$Comp\n'] - if component.labels: - line = 'L ' - for key in component._L_KEYS: - line += component.labels[key] + ' ' - to_write += [line.rstrip() + '\n'] - - if component.unit: - line = 'U ' - for key in component._U_KEYS: - line += component.unit[key] + ' ' - to_write += [line.rstrip() + '\n'] - - if component.position: - line = 'P ' - for key in component._P_KEYS: - line += component.position[key] + ' ' - to_write += [line.rstrip() + '\n'] - - for reference in component.references: - if component.references: - line = 'AR ' - for key in component._AR_KEYS: - line += reference[key] + ' ' - to_write += [line.rstrip() + '\n'] - - for field in component.fields: - line = 'F ' - for key in component._F_KEYS: - line += field[key] + ' ' - to_write += [line.rstrip() + '\n'] - - if component.old_stuff: - to_write += component.old_stuff - - to_write += ['$EndComp\n'] - - # Bitmaps - for bitmap in self.bitmaps: - to_write += bitmap.raw_data - - # Texts - for text in self.texts: - to_write += [text['desc'], text['data']] - - # Wires - for wire in self.wires: - to_write += [wire['desc'], wire['data']] - - # Entries - for entry in self.entries: - to_write += [entry['desc'], entry['data']] - - # Connections - for conn in self.conns: - to_write += [conn['desc']] - - # No Connetions - for noconn in self.noconns: - to_write += [noconn['desc']] - - to_write += ['$EndSCHEMATC\n'] - - f = open(filename, 'w') - f.writelines(to_write) diff --git a/.v5_sch/test_sch.sh b/.v5_sch/test_sch.sh deleted file mode 100755 index 6a4bf378..00000000 --- a/.v5_sch/test_sch.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -# This script file is used to test the consistency of files saved -# from sch python class. Spaces and line positioning will be ignored - -if [[ $# < 1 ]]; then - echo "Usage: $0 sch_files" - exit 1 -fi - -function test_sch { - filename=`basename "$1"` - -# python code --- START -python << EOF -from sch import * -lib = Schematic('$1') -lib.save('/tmp/$filename') -EOF -# python code --- END - - sort "$1" > "/tmp/$filename.original.sorted" - sort "/tmp/$filename" > "/tmp/$filename.sch.sorted" - [[ `diff -b /tmp/$filename.original.sorted /tmp/$filename.sch.sorted` ]] && return 0 - return 1 -} - -# colors -RED="\e[0;31m" -NOCOLOR="\e[0m" - -for file in "$@"; do - echo "* testing $file" - if ( test_sch "$file" ); then - echo -e "${RED}sch class has generated a non identical output for the file: $file${NOCOLOR}" - fi -done diff --git a/.v5_sch/update_footprints.py b/.v5_sch/update_footprints.py deleted file mode 100755 index b38340b0..00000000 --- a/.v5_sch/update_footprints.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from __future__ import print_function -from sch import * -import argparse -import csv, sys - -parser = argparse.ArgumentParser('This script updates the footprints fields of sch files using a csv as input') -parser.add_argument('sch_file', nargs='+') -parser.add_argument('--bom-csv', help='a BOM csv file that will be used to fill the footprint field', action='store') -parser.add_argument('--bom-ref-field', help='defines the reference field name in the BOM', action='store', default='Reference(s)') -parser.add_argument('--bom-fp-field', help='defines the footprint field name in the BOM', action='store', default='Footprint') -args = parser.parse_args() -bom = [] - -if args.bom_csv: - f = open(args.bom_csv, 'r') - reader = csv.reader(f) - header_ok = False - for row in reader: - # Try to locate the header row - if args.bom_ref_field in row and args.bom_fp_field in row: - header_ok = True - ref_col = row.index(args.bom_ref_field) - fp_col = row.index(args.bom_fp_field) - - elif header_ok: - bom.append(row) - - if not header_ok: - sys.stderr.write('Cannot find a header with one or both fields: "%s", "%s"\n' % (args.bom_ref_field, args.bom_fp_field)) - sys.exit() - -for f in args.sch_file: - sch = Schematic(f) - - for component in sch.components: - # check if is power related component - if '#PWR' in component.fields[0]['ref'] or\ - 'PWR_FLAG' in component.fields[1]['ref']: - continue - - # component reference - comp_ref = component.fields[0]['ref'].replace('"', '') - - # search the component in the BOM items and get the PN - for item in bom: - item_refs = item[ref_col].replace(' ', '').split(',') - if item[fp_col] and comp_ref in item_refs: - # set component footprint - component.fields[2]['ref'] = '"' + item[fp_col] + '"' - break - - sch.save()