def get_parts(self, use_backup_lib=True, **criteria): """ Return parts from a library that match *all* the given criteria. Keyword Args: criteria: One or more keyword-argument pairs. The keyword specifies the attribute name while the argument contains the desired value of the attribute. Returns: A single Part or a list of Parts that match all the criteria. """ import skidl parts = list_or_scalar(filter_list(self.parts, **criteria)) if not parts and use_backup_lib and skidl.QUERY_BACKUP_LIB: try: backup_lib_ = skidl.load_backup_lib() parts = backup_lib_.get_parts(use_backup_lib=False, **criteria) except AttributeError: pass return parts
def __init__(self, lib=None, name=None, dest=NETLIST, tool=None, connections=None, part_defn=None, circuit=None, **attribs): import skidl from .SchLib import SchLib from .defines import TEMPLATE, NETLIST, LIBRARY, SKIDL super(Part, self).__init__() if tool is None: tool = skidl.get_default_tool() # Setup some part attributes that might be overwritten later on. self.do_erc = True # Allow part to be included in ERC. self.unit = { } # Dictionary for storing subunits of the part, if desired. self.pins = [] # Start with no pins, but a place to store them. self.name = name # Assign initial part name. (Must come after circuit is assigned.) self.description = '' # Make sure there is a description, even if empty. self._ref = '' # Provide a member for holding a reference. self.ref_prefix = '' # Provide a member for holding the part reference prefix. self.tool = tool # Initial type of part (SKIDL, KICAD, etc.) self.circuit = None # Part starts off unassociated with any circuit. # Create a Part from a library entry. if lib: # If the lib argument is a string, then create a library using the # string as the library file name. if isinstance(lib, basestring): try: libname = lib lib = SchLib(filename=libname, tool=tool) except Exception as e: if skidl.QUERY_BACKUP_LIB: logger.warning( 'Could not load KiCad schematic library "{}", falling back to backup library.' .format(libname)) lib = skidl.load_backup_lib() if not lib: raise e else: raise e # Make a copy of the part from the library but don't add it to the netlist. part = lib[name].copy(dest=TEMPLATE) # Overwrite self with the new part. self.__dict__.update(part.__dict__) # Make sure all the pins have a valid reference to this part. self.associate_pins() # Store the library name of this part. self.lib = getattr(lib, 'filename', None) # Otherwise, create a Part from a part definition. If the part is # destined for a library, then just get its name. If it's going into # a netlist, then parse the entire part definition. elif part_defn: self.part_defn = part_defn self.parse(just_get_name=(dest != NETLIST)) # If the part is destined for a SKiDL library, then it will be defined # by the additional attribute values that are passed. elif tool == SKIDL and name: pass else: logger.error( "Can't make a part without a library & part name or a part definition." ) raise Exception # If the part is going to be an element in a circuit, then add it to the # the circuit and make any indicated pin/net connections. if dest != LIBRARY: if dest == NETLIST: # If no Circuit object is given, then use the default Circuit that always exists. # Always set circuit first because naming the part requires a lookup # of existing names in the circuit. if not circuit: circuit = default_circuit # pylint: disable=undefined-variable circuit += self elif dest == TEMPLATE: # If this is just a part template, don't add the part to the circuit. # Just place the reference to the Circuit object in the template. if not circuit: self.circuit = default_circuit # pylint: disable=undefined-variable self.circuit = circuit # Add any net/pin connections to this part that were passed as arguments. if isinstance(connections, dict): for pin, net in connections.items(): net += self[pin] # Add any other passed-in attributes to the part. for k, v in attribs.items(): setattr(self, k, v)
def __init__(self, lib=None, name=None, dest=NETLIST, tool=None, connections=None, part_defn=None, circuit=None, **attribs): import skidl from .SchLib import SchLib super().__init__() if tool is None: tool = skidl.get_default_tool() # Setup some part attributes that might be overwritten later on. self.do_erc = True # Allow part to be included in ERC. self.unit = { } # Dictionary for storing subunits of the part, if desired. self.pins = [] # Start with no pins, but a place to store them. self.p = PinNumberSearch( self) # Does pin search using only pin numbers. self.n = PinNameSearch(self) # Does pin search using only pin names. self.name = name # Assign initial part name. self.description = "" # Make sure there is a description, even if empty. self._ref = "" # Provide a member for holding a reference. self.ref_prefix = "" # Provide a member for holding the part reference prefix. self.tool = tool # Initial type of part (SKIDL, KICAD, etc.) self.circuit = None # Part starts off unassociated with any circuit. self.match_pin_substring = False # Only select pins with exact name matches. # Create a Part from a library entry. if lib: # If the lib argument is a string, then create a library using the # string as the library file name. if isinstance(lib, basestring): libname = lib try: lib = SchLib(filename=libname, tool=tool) except FileNotFoundError as e: if skidl.QUERY_BACKUP_LIB: logger.warning( 'Could not load KiCad schematic library "{}", falling back to backup library.' .format(libname)) lib = skidl.load_backup_lib() if not lib: raise e else: raise e # Make a copy of the part from the library but don't add it to the netlist. part = lib[name].copy(dest=TEMPLATE) # Overwrite self with the new part. self.__dict__.update(part.__dict__) # Replace the fields with a copy that points to self. self.fields = part.fields.copy(attr_obj=self) # Make sure all the pins have a valid reference to this part. self.associate_pins() # Store the library name of this part. self.lib = getattr(lib, "filename", None) # Otherwise, create a Part from a part definition. If the part is # destined for a library, then just get its name. If it's going into # a netlist, then parse the entire part definition. elif part_defn: self.part_defn = part_defn self.parse(get_name_only=(dest != NETLIST)) # If the part is destined for a SKiDL library, then it will be defined # by the additional attribute values that are passed. elif tool == SKIDL and name: pass else: log_and_raise( logger, ValueError, "Can't make a part without a library & part name or a part definition.", ) # If the part is going to be an element in a circuit, then add it to the # the circuit and make any indicated pin/net connections. if dest != LIBRARY: # If no Circuit object is given, then use the default Circuit that always exists. circuit = circuit or default_circuit if dest == NETLIST: circuit += self elif dest == TEMPLATE: # If this is just a part template, don't add the part to the circuit. # Just place the reference to the Circuit object in the template. self.circuit = circuit # Add any net/pin connections to this part that were passed as arguments. if isinstance(connections, dict): for pin, net in list(connections.items()): net += self[pin] # Add any XSPICE I/O as pins. (This only happens with SPICE simulations.) self.add_xspice_io(attribs.pop("io", [])) # Add any other passed-in attributes to the part. for k, v in list(attribs.items()): setattr(self, k, v)
def __init__( self, lib=None, name=None, dest=NETLIST, tool=None, connections=None, part_defn=None, circuit=None, **kwargs ): import skidl from .schlib import SchLib super().__init__() if tool is None: tool = skidl.get_default_tool() # Setup some part attributes that might be overwritten later on. self.do_erc = True # Allow part to be included in ERC. self.unit = {} # Dictionary for storing subunits of the part, if desired. self.pins = [] # Start with no pins, but a place to store them. self.p = PinNumberSearch(self) # Does pin search using only pin numbers. self.n = PinNameSearch(self) # Does pin search using only pin names. self.name = name # Assign initial part name. self.description = "" # Make sure there is a description, even if empty. self._ref = "" # Provide a member for holding a reference. self.ref_prefix = "" # Provide a member for holding the part reference prefix. self.tool = tool # Initial type of part (SKIDL, KICAD, etc.) self.circuit = None # Part starts off unassociated with any circuit. self.match_pin_regex = False # Don't allow regex matches of pin names. # Remove a part reference if it has been explicitly set as None. # Otherwise, this causes the assigned part reference to be incremented twice: # once by Circuit.add_parts() and again by setattr(). ref = kwargs.pop("ref", None) if ref: kwargs["ref"] = ref # Create a Part from a library entry. if lib: # If the lib argument is a string, then create a library using the # string as the library file name. if isinstance(lib, basestring): libname = lib try: lib = SchLib(filename=libname, tool=tool) except FileNotFoundError as e: if skidl.QUERY_BACKUP_LIB: logger.warning( 'Could not load KiCad schematic library "{}", falling back to backup library.'.format( libname ) ) lib = skidl.load_backup_lib() if not lib: raise e else: raise e # Make a copy of the part from the library but don't add it to the netlist. part = lib[name].copy(dest=TEMPLATE) # Overwrite self with the new part. self.__dict__.update(part.__dict__) # Make sure all the pins have a valid reference to this part. self.associate_pins() # Copy part units so all the pin and part references stay valid. self.copy_units(part) # Otherwise, create a Part from a part definition. If the part is # destined for a library, then just get its name. If it's going into # a netlist, then parse the entire part definition. elif part_defn: self.part_defn = part_defn # If given, set the tool version before parsing the part definition. # At this time, this is done to support differences between KiCad V5 and V6. tool_version = kwargs.pop("tool_version", None) if tool_version: self.tool_version = tool_version self.parse(get_name_only=(dest != NETLIST)) # If the part is destined for a SKiDL library, then it will be defined # by the additional attribute values that are passed. elif tool == SKIDL and name: pass else: log_and_raise( logger, ValueError, "Can't make a part without a library & part name or a part definition.", ) # Split multi-part pin names into individual pin aliases. self.split_pin_names(kwargs.pop("pin_splitters", None)) # Setup the tag for tieing the part to a footprint in a pcb editor. # Use the user specified tag if present. tag = kwargs.pop("tag", None) if tag is not None: self.tag = tag else: self.tag = str(randint(0, 2 ** 64 - 1)) if dest != LIBRARY: if dest == NETLIST: # If the part is going to be an element in a circuit, then add it to the # the circuit and make any indicated pin/net connections. # If no Circuit object is given, then use the default Circuit that always exists. circuit = circuit or default_circuit circuit += self elif dest == TEMPLATE: # If this is just a part template, don't add the part to the circuit. self.circuit = None # Add any net/pin connections to this part that were passed as arguments. if isinstance(connections, dict): for pin, net in list(connections.items()): net += self[pin] # Add any XSPICE I/O as pins. (This only happens with SPICE simulations.) self.add_xspice_io(kwargs.pop("io", [])) # Add any other passed-in attributes to the part. for k, v in list(kwargs.items()): setattr(self, k, v)
def __init__(self, lib=None, name=None, dest=NETLIST, tool=None, connections=None, part_defn=None, circuit=None, **attribs): import skidl from .SchLib import SchLib from .defines import TEMPLATE, NETLIST, LIBRARY, SKIDL if tool is None: tool = skidl.get_default_tool() # Setup some part attributes that might be overwritten later on. self.do_erc = True # Allow part to be included in ERC. self.unit = { } # Dictionary for storing subunits of the part, if desired. self.pins = [] # Start with no pins, but a place to store them. self.name = name # Assign initial part name. (Must come after circuit is assigned.) self.description = '' # Make sure there is a description, even if empty. self._ref = '' # Provide a member for holding a reference. self.ref_prefix = '' # Provide a member for holding the part reference prefix. self.tool = tool # Initial type of part (SKIDL, KICAD, etc.) self.circuit = None # Part starts off unassociated with any circuit. # Create a Part from a library entry. if lib: # If the lib argument is a string, then create a library using the # string as the library file name. if isinstance(lib, basestring): try: libname = lib lib = SchLib(filename=libname, tool=tool) except Exception as e: if skidl.QUERY_BACKUP_LIB: logger.warning( 'Could not load KiCad schematic library "{}", falling back to backup library.' .format(libname)) lib = skidl.load_backup_lib() if not lib: raise e else: raise e # Make a copy of the part from the library but don't add it to the netlist. part = lib[name].copy(dest=TEMPLATE) # Overwrite self with the new part. self.__dict__.update(part.__dict__) # Make sure all the pins have a valid reference to this part. self.associate_pins() # Store the library name of this part. self.lib = getattr(lib, 'filename', None) # Otherwise, create a Part from a part definition. If the part is # destined for a library, then just get its name. If it's going into # a netlist, then parse the entire part definition. elif part_defn: self.part_defn = part_defn self.parse(just_get_name=(dest != NETLIST)) # If the part is destined for a SKiDL library, then it will be defined # by the additional attribute values that are passed. elif tool == SKIDL and name: pass else: logger.error( "Can't make a part without a library & part name or a part definition." ) raise Exception # If the part is going to be an element in a circuit, then add it to the # the circuit and make any indicated pin/net connections. if dest != LIBRARY: if dest == NETLIST: # If no Circuit object is given, then use the default Circuit that always exists. # Always set circuit first because naming the part requires a lookup # of existing names in the circuit. if not circuit: circuit = default_circuit # pylint: disable=undefined-variable circuit += self elif dest == TEMPLATE: # If this is just a part template, don't add the part to the circuit. # Just place the reference to the Circuit object in the template. if not circuit: self.circuit = default_circuit # pylint: disable=undefined-variable self.circuit = circuit # Add any net/pin connections to this part that were passed as arguments. if isinstance(connections, dict): for pin, net in connections.items(): net += self[pin] # Add any other passed-in attributes to the part. for k, v in attribs.items(): setattr(self, k, v)