def reset(self, item): """Reset refdes object.""" if item.value == '?': return message('Resetting Component: {}'.format(item.string), 'I') item.value = '?' self.changes += 1
def print_stat(self, env): message("Statistics:") message("===========\n") for path in env.schematic_files: self.sch_stat(path) self.pcb_stat(env.pcb_file)
def check_project_file(self, file=None): """Check project file for all options needed.""" if not file: return self.config = ConfigParser.ConfigParser() self.config.readfp(open(file)) # check inventory self.inventory_server = self.get_config('Inventory', 'url') # checking files sch_files = self.get_config('Files', 'schematic', " ") self.schematic_files = sch_files.split(',') # checking other options self.pcb_file = self.get_config('Files', 'pcb') self.output_path = self.get_config('Files', 'output path') self.project_package_path = self.get_config('Files', 'package path') if self.project_package_path: self.package_path.append(self.project_package_path) # check section Options self.project_name = self.get_config('Options', 'project name') if self.project_name is None: message('No project name specified.', level="W") self.project_number = self.get_config('Options', 'project number') self.pcb_version = self.get_config('Options', 'pcb version')
def __init__(self): # getting system information (GSCHEM) try: gEDA_path = subprocess.check_output(["type", "-p", 'gschem']).strip() gEDA_path = os.path.realpath(gEDA_path) gEDA_path = os.path.split(gEDA_path)[0] self.gEDA_path = os.path.split(gEDA_path)[0] if not os.path.isdir(self.gEDA_path): raise exceptions.IOError("'gschem' application not found.") except (exceptions.IOError, subprocess.CalledProcessError): raise exceptions.IOError("'gschem' application not found.") # getting system information (PCB) try: pcb_path = subprocess.check_output(["type", "-p", 'pcb']).strip() pcb_path = os.path.realpath(pcb_path) pcb_path = os.path.split(pcb_path)[0] self.pcb_path = os.path.split(pcb_path)[0] if not os.path.isdir(self.pcb_path): raise IOError("'pcb' application not found.") except (exceptions.IOError, subprocess.CalledProcessError): message("'pcb' application not found.", level="W") # collect symbol paths for path in self.gschem_properties('component-library'): self.symbol_path.append(path.strip('"')) self.symbol_path.append(self.gEDA_path+'/share/gEDA/sym') # collect packages self.package_path.append('./packages') if self.pcb_path: self.package_path.append(self.pcb_path+'/share/pcb/newlib') self.package_path.append(self.pcb_path+'/share/pcb/pcblib-newlib')
def __init__(self): # getting system information (GSCHEM) try: gEDA_path = subprocess.check_output(["type", "-p", 'gschem']).strip() gEDA_path = os.path.realpath(gEDA_path) gEDA_path = os.path.split(gEDA_path)[0] self.gEDA_path = os.path.split(gEDA_path)[0] if not os.path.isdir(self.gEDA_path): raise exceptions.IOError("'gschem' application not found.") except (exceptions.IOError, subprocess.CalledProcessError): raise exceptions.IOError("'gschem' application not found.") # getting system information (PCB) try: pcb_path = subprocess.check_output(["type", "-p", 'pcb']).strip() pcb_path = os.path.realpath(pcb_path) pcb_path = os.path.split(pcb_path)[0] self.pcb_path = os.path.split(pcb_path)[0] if not os.path.isdir(self.pcb_path): raise IOError("'pcb' application not found.") except (exceptions.IOError, subprocess.CalledProcessError): message("'pcb' application not found.", level="W") # collect symbol paths for path in self.gschem_properties('component-library'): self.symbol_path.append(path.strip('"')) self.symbol_path.append(self.gEDA_path + '/share/gEDA/sym') # collect packages self.package_path.append('./packages') if self.pcb_path: self.package_path.append(self.pcb_path + '/share/pcb/newlib') self.package_path.append(self.pcb_path + '/share/pcb/pcblib-newlib')
def process_component(self, component): ret = 0 unique_id = component.attribute('uid') if not unique_id: new = Attribute(['T', component.x, component.y, 0, 10, 0, 2, 0, 0, 1]) uid = self._new_uid() new.key = 'uid' new.value = uid component.attributes.append(new) message('Adding UID {}. ({})'.format( str(component.attribute('uid').value), component.refdes.string), 'I') ret = 1 else: if unique_id.value in self.uids: new_uid = self._new_uid() message('Changing UID {} to {}. ({})'.format( str(unique_id.value), new_uid, component.refdes.string), 'W') unique_id.value = new_uid ret = 1 else: self.uids.append(unique_id.value) return ret
def open(self): try: self.fh = open(self.path) message("File '{}' open.".format(self.path), 'D') return True except IOError: message("File '{}' doesn't exist.".format(self.path), 'E') return False
def add(self, item, reset=False): """Add object to pool.""" if not item: return if item.value in self.values(item.base): if reset: self.reset(item) else: message('Duplicate {}'.format(item.string), 'E') raise SchematicException('Duplicate Refdes') self.pool.append(item)
def enumerate(self, sort=None): """Enumerate all objects.""" if sort: self.sort(sort) while True: item = self.next_undefined() if not item: return value = self.next_value(item.base) item.value = str(value) message('Naming Component: {}'.format(item.string), 'I') self.changes += 1
def process_file(self, path): """Process schematic file.""" message('Processing file: {}'.format(path)) sch = Schematic(path) sch.open() sch.parse() sch.close() ret = 0 pool = RefdesPool() for component in sch.components: pool.add(component.refdes, reset=(self.env.args.reset or self.env.args.duplicates)) if self.env.args.reset: pool.reset_all() if not self.env.args.no_enum: pool.enumerate(sort=self.env.args.sort) if pool.changes == 0: message('No references where changed.', 'I') else: message('{} changes made.'.format(pool.changes), 'I') if self.env.args.dry: message('Dry mode - not writing anything.', 'W') return ret fhandler = open(path, 'w') sch.write(fhandler) return ret
def process_file(self, path): message('Processing file: {}'.format(path)) ret = 0 sch = Schematic(path) sch.open() sch.parse() sch.close() self.uids = [] for component in sch.components: ret += self.process_component(component) if ret == 0: message('All components are unique.', 'I') else: message('{} changes made.'.format(ret), 'I') if self.env.args.dry: message('Dry mode - not writing anything.', 'W') return ret fh = open(path, 'w') sch.write(fh) return ret
def parse(self): """Reads and parses a schematic file.""" try: line = self._next_line self.version = component_for_line(self._split(line)) message("Schematic File Verion: {}".format(self.version.version), 'D') message( "Schematic File Format: " "{}".format(self.version.fileformat_version), 'D') self.objects.append(self.version) except Exception as exception: raise SchematicException() if not self.version.fileformat_version == 2: message('File Version {} is not supported'.format( self.version.fileformat_version)) lnr = 0 component = None parent = None line = self._next_line while line: if component and lnr < component.num_lines: component.append_text(line) lnr += 1 elif line == '{': parent = component elif line == '}': parent = None elif parent: line = self._split(line) component = Attribute(line) lnr = 0 parent.attributes.append(component) else: line = self._split(line) component = component_for_line(line) lnr = 0 self.objects.append(component) line = self._next_line
def parse(self): """Reads and parses a schematic file.""" try: line = self._next_line self.version = component_for_line(self._split(line)) message("Schematic File Verion: {}".format(self.version.version), 'D') message("Schematic File Format: " "{}".format(self.version.fileformat_version), 'D') self.objects.append(self.version) except Exception as exception: raise SchematicException() if not self.version.fileformat_version == 2: message('File Version {} is not supported'.format( self.version.fileformat_version)) lnr = 0 component = None parent = None line = self._next_line while line: if component and lnr < component.num_lines: component.append_text(line) lnr += 1 elif line == '{': parent = component elif line == '}': parent = None elif parent: line = self._split(line) component = Attribute(line) lnr = 0 parent.attributes.append(component) else: line = self._split(line) component = component_for_line(line) lnr = 0 self.objects.append(component) line = self._next_line
def run(self, env): self.env = env for path in env.schematic_files: self.validate_file(path) message('=== DONE ===') order = 1 if not self.needed_tasks: message('No issues found.') exit(0) message('Please fix all issues in the given order:') if 'manual' in self.needed_tasks: message('{}) fix issues marked as manually'.format(order)) order += 1 if 'unique' in self.needed_tasks: message('{}) run pygeda unique'.format(order)) order += 1 if 'refdes -f' in self.needed_tasks: message('{}) run pygeda refdes -f'.format(order)) order += 1 elif 'refdes' in self.needed_tasks: message('{}) run pygeda refdes'.format(order)) order += 1 exit(1)
def message_path(self, env): message('gEDA: {}'.format(env.gEDA_path)) message('PCB : {}'.format(env.pcb_path)) message('Symbols:') for path in env.symbol_path: message(' {}'.format(path)) message('Packages:') for path in env.package_path: message(' {}'.format(path)) message('Schematic Files:') for path in env.schematic_files: message(' {}'.format(path)) message('PCB File:') message(' {}'.format(env.pcb_file)) message('Output Path:') message(' {}'.format(env.output_path))
def sch_stat(self, path): message('File {}'.format(path)) sch = pygeda.lib.schem.Schematic(path) sch.open() sch.parse() sch.close() stat = {'unique': 0, 'rerdes':0} uids = [] for component in sch.components: if component.refdes.is_set: stat['refdes'] = stat.get('refdes', 0) + 1 uuid = component.uuid if uuid and uuid not in uids: stat['unique'] = stat.get('unique', 0) + 1 uids.append(uuid) elif uuid: stat['duplicate'] = stat.get('duplicate', 0) + 1 message(" Object Count : {}".format(len(sch.objects))) message(" Components : {}".format(len(sch.components))) message(" with refdes: {}".format(stat.get('refdes', 0))) message(" unique : {}".format(stat.get('unique', 0))) message(" duplicate : {}".format(stat.get('duplicate', 0))) message(" Net Fragments : {}".format(len(sch.get_by_type('N'))))
def pcb_stat(self, path): message('File {}'.format(path)) pcb = pygeda.lib.pcb.PCBFile(path) pcb.open() pcb.parse() pcb.close()
def validate_file(self, path): message('Checking file: %s' % path) sch = pygeda.lib.schem.Schematic(path) sch.open() sch.parse() sch.close() nets = sch.get_by_type('N') # Stats message('Found %d Components.' % len(sch.components)) message('Found %d Unique Components.' % len(sch.unique_components)) message('Found %d Nets.' % len(nets)) # Check nets for net in nets: if math.hypot(abs(net.x1-net.x2), abs(net.y1-net.y2)) == 0.0: message('Net object with the length of 0.0 at ({}, {}). Fix ' 'this issue manually.'.format(net.x1, net.y1), 'W') self.needed_tasks.append('manual') if abs(net.x1-net.x2) and abs(net.y1-net.y2): message('None orthogonal net at ({}, {}). Fix this issue ' 'manually.'.format(net.x1, net.y1), 'W') self.needed_tasks.append('manual') # Check components refdes_list = [] for comp in sch.components: footprint = comp.attribute('footprint') refdes = comp.refdes if not refdes.is_set: message('Designator of {} is not set.'.format(refdes), 'E') self.needed_tasks.append('refdes') if not self.env.sym_files(comp.basename): message('Symbol \'{}\' for {} not found.'.format(comp.basename, refdes), 'E') self.needed_tasks.append('manually') if not footprint: message('Footprint for {} not defined.'.format(refdes), 'E') self.needed_tasks.append('manually') elif not self.env.package_files(footprint.value): message('Footprint \'{}\' for {} not found.' ''.format(footprint.value, refdes), 'E') self.needed_tasks.append('manually') if not comp.uuid: message('UUID of {} is not unique.'.format(refdes), 'E') self.needed_tasks.append('unique') if comp.refdes.string in refdes_list: message('Designator of {} is not unique.'.format(refdes), 'E') self.needed_tasks.append('refdes -f') if refdes.is_set: refdes_list.append(refdes.string)