예제 #1
0
    def extractCsvComponents(self):
        if globals.CsvSeparator not in self.contents[1]:
            return 'error: no delimiter found in CSV. ' + '"' + globals.CsvSeparator + '" expected. See config.ini'

        # Find the order of the parameters saved in the csv
        header = self.contents[0]
        header = header.strip('\n')
        header = header.strip('\r')
        columnNames = header.split(globals.CsvSeparator)

        if len(columnNames) < 7:
            return 'error: missing delimiter(s) in CSV. ' + 'At least 7 occurrences of "' + globals.CsvSeparator + '" expected. See config.ini'

        for c in columnNames:
            new_csv_field = KicadField()
            new_csv_field.name = c
            self.fieldList.append(new_csv_field)

        #parse date belonging to component
        for i in range(1, len(self.contents)):
            newCsvComponent = CsvComponent()

            dataLine = self.contents[i]
            newCsvComponent.Contents = self.contents[i]

            dataLine = dataLine.strip('\n')
            dataLine = dataLine.strip('\r')
            values = dataLine.split(globals.CsvSeparator)

            column = 0
            for value in values:
                # TODO 3: replace these constants with a common definition in globals
                if columnNames[column] == 'Part':
                    newCsvComponent.name = value
                elif columnNames[column] == 'Reference':
                    newCsvComponent.reference = value
                elif columnNames[column] == 'Unit':
                    newCsvComponent.unit = value
                elif columnNames[column] == 'Value':
                    newCsvComponent.value = value
                elif columnNames[column] == 'Footprint':
                    newCsvComponent.footprint = value
                elif columnNames[column] == 'Datasheet':
                    newCsvComponent.datasheet = value
                elif columnNames[column] == 'File':
                    newCsvComponent.schematic = value
                else:
                    newCsvComponent.propertyList.append(
                        [self.fieldList[column], value])

                column += 1
            # end for all values in dataLine

            self.components.append(newCsvComponent)

        DT.info("finished component extractions")
    def extractCsvComponents(self, filename: str):
        self.deleteContents()

        try:
            with open(filename, newline='\n') as csvfile:
                reader = csv.DictReader(csvfile,
                                        delimiter=globals.CsvSeparator,
                                        quotechar='"')

                if len(reader.fieldnames) < 7:
                    return 'error: missing delimiter(s) in CSV. ' + 'At least 7 occurrences of "' + globals.CsvSeparator + '" expected. See config.ini'

                for c in reader.fieldnames:
                    new_csv_field = KicadField()
                    new_csv_field.name = c
                    self.fieldList.append(new_csv_field)

                # get property field names:
                propertyFieldNames = copy.deepcopy(reader.fieldnames)
                for mand in self.MandatoryFields:
                    propertyFieldNames.remove(mand)
                if 'Index' in propertyFieldNames:
                    propertyFieldNames.remove('Index')

                DT.info('Property field names in CSV: ' +
                        str(propertyFieldNames))

                for row in reader:
                    # parse data belonging to component
                    newCsvComponent = CsvComponent()

                    # TODO 3: replace these constants with a common definition in globals
                    newCsvComponent.name = row['Part']
                    newCsvComponent.reference = row['Reference']
                    newCsvComponent.unit = row['Unit']
                    newCsvComponent.value = row['Value']
                    newCsvComponent.footprint = row['Footprint']
                    newCsvComponent.datasheet = row['Datasheet']
                    newCsvComponent.schematic = row['File']

                    for key in propertyFieldNames:
                        newCsvComponent.propertyDict[key] = row[key]

                    self.components.append(newCsvComponent)

                csvfile.close()
        except EnvironmentError as e:
            return str(e)

        DT.info("finished component extractions")
def load_csv():
	DT.clear()

	config = ConfigParser()
	config.read('config.ini')

	initialDirectory = config.get('main', 'lastDirectory', fallback="")

	#mainSchematicFile.printprops()
	if initialDirectory == "":
		root.filename = filedialog.askopenfilename(
			filetypes=(("KiCAD Partslist-editor files", ".csv"), ("All Files", ".*")))
	else:
		root.filename = filedialog.askopenfilename(initialdir=initialDirectory, filetypes=(
		("KiCAD Partslist-editor files", ".csv"), ("All Files", ".*")))

	filename = root.filename

	config.read('config.ini')
	if config.has_section('main') == FALSE:
		config.add_section('main')
	config.set('main', 'lastDirectory', os.path.dirname(filename))
	with open('config.ini', 'w') as f:
		config.write(f)

	
	if filename[-4:] == ".csv" or filename[-4:] == ".CSV":
		error = csvFile.extractCsvComponents(filename)
		if error:
			messagebox.showerror("Incorrect Fileformat", error)
		else:
			statusLabel['text'] = "Import: " + str(root.filename) + " complete" + "\n" +  str(len(csvFile.components)) + " components were imported"

		f.close()

	else:
		if filename:
			messagebox.showerror("FileParseError", "This is not a valid CSV document (*.csv or *.CSV)")

	print("Summary for importing from CSV: ")
	DT.summary()

	DT.info(str(len(csvFile.components)) + ' components were imported from CSV')
예제 #4
0
    def extractProperties(self):

        # temporary dictionay, if we have all fields found
        fieldFound = {}
        for anyField in self.fieldList:
            fieldFound[anyField] = False

        fieldTemplate = ""  # used for new extra fields
        maxFieldNr = 3  # used for new extra fields; 0 to 3 are default fields
        lastExistingFieldLine = 0  # used for adding new extra fields; relative to $COMP (which is zero)

        for line_nr in range(len(self.contents)):
            line = self.contents[line_nr]

            # Example for a resistor with component=R and ref=R609
            # L R R609
            # the reference here is a common reference, if it is used in multiple instances of a subsheet
            if line[0] == "L":
                searchResult = re.search('L +(.*) +(.*)', line)

                if searchResult:
                    componentName = searchResult.group(1)
                    componentRef = searchResult.group(2)

                    self.reference = componentRef
                    self.name = componentName

                    DT.debug("Found Component: " + componentName + " " +
                             componentRef)

                    # Special case for power-components: don't parse them
                    if componentRef[0] == "#":
                        self.unlisted = True
                        return  # no further parsing for unlisted components

                    continue

                else:
                    DT.error("Regex Missmatch for L-record in line: " + line +
                             " in file " + self.schematicName)
                # endelse
            # endif L

            # Unit: Example
            # U 1 1 5873950B
            if line[0:2] == "U ":
                searchResult = re.search('U +(\d*) +(\d+) +([0-9A-Fa-f]+) *',
                                         line)

                if searchResult:
                    componentUnit = searchResult.group(1)
                    componentMm = searchResult.group(
                        2
                    )  # could not find a proper meaning of this value other than 'mm'
                    componentTimestamp = searchResult.group(3)  # unused here
                    self.unit = componentUnit
                    continue
                else:
                    DT.error("Regex Missmatch for 'U '-record in line: " +
                             line + " in file " + self.schematicName)
                # end else
            # endif U

            # Example:
            # AR Path="/56647084/5664BC85" Ref="U501"  Part="2"
            # the number for Part= varies e.g. from 1 to 4 for a component with 4 Units (e.g. LM324)
            # NOTE; it is not clear, for what reason we get this record only for some components...
            # we print just a message
            # for now, we don't use the data any further
            if "AR Path=" in line:
                # extract the path, Ref and Part into regex groups:
                searchResult = re.search(
                    'AR +Path="(.*)" +Ref="(.*)" +Part="(.*)".*', line)

                if searchResult:
                    componentPath = searchResult.group(1)
                    componentRef = searchResult.group(2)
                    componentUnit = searchResult.group(3)

                    # Print some messages
                    DT.debug('AR Record: ' + componentPath + ' ' +
                             componentRef + ' ' + componentUnit)

            # Example
            # F 0 "R51" H 5820 2046 50  0000 L CNN
            if line[0:4] == "F 0 ":
                if line_nr > lastExistingFieldLine:
                    lastExistingFieldLine = line_nr

                searchResult = re.search('F 0 +"(.*)" +.*', line)

                if searchResult:
                    componentRef = searchResult.group(1)

                    # TODO 1: handle proper reference name for multiple instances
                    # we get the unique references only from the AR-records!!!

                    #self.referenceUnique = componentRef

                    if not (componentRef == self.reference):
                        DT.info("L record value doesn't match 'F 0 ' record: "\
                           + self.reference + " vs. " + componentRef + " in '" +\
                          line + "' in file " + self.schematicName + ". Using 'F 0' records value: " + componentRef)
                        self.reference = componentRef
                    continue
                else:
                    DT.error("Regex Missmatch for 'F 0 '-record in line: " +\
                       line + " in file " + self.schematicName)
                # endelse
            # endif F 0

            # Value, Example:
            # F 1 "LTC2052IS#PBF" H 9750 5550 50  0000 C CNN
            if "F 1 " in line:  # find f1 indicating value field in EEschema file format
                if line_nr > lastExistingFieldLine:
                    lastExistingFieldLine = line_nr

                searchResult = re.search('F 1 +"(.*)".*', line)

                if searchResult:
                    componentValue = searchResult.group(1)
                    self.value = componentValue
                    continue
                else:
                    DT.error(
                        "Regex Mismatch, cannot find value in 'F 1 '-record in '"
                        + line + "' in file " + self.schematicName)
                # end if
            # endif F 1

            # Footprint, Example:
            # F 2 "standardSMD:R0603" V 5680 2000 50  0001 C CNN
            if "F 2 " in line:  # find f2 indicating Footprint field in EEschema file format
                if line_nr > lastExistingFieldLine:
                    lastExistingFieldLine = line_nr

                searchResult = re.search('F 2 +"(.*)".*', line)

                if searchResult:
                    componentFootprint = searchResult.group(1)
                    self.footprint = componentFootprint
                    continue
                else:
                    DT.error(
                        "Regex Mismatch, cannot find value in 'F 2 '-record (footprint) in '"
                        + line + "' in file " + self.schematicName)
                # end if
                # endif F 2

            #
            # Datasheet; Example:
            # F 3 "" H 5750 2000 50  0000 C CNN
            if "F 3 " in line:  # find f3 indicating Datasheet field in EEschema file format
                if line_nr > lastExistingFieldLine:
                    lastExistingFieldLine = line_nr

                fieldTemplate = line  # use the Datasheet field as a template for new extra fields

                searchResult = re.search('F 3 +"(.*)".*', line)

                if searchResult:
                    componentDatasheet = searchResult.group(1)
                    self.datasheet = componentDatasheet
                    continue
                else:
                    DT.error(
                        "Regex Mismatch, cannot find value in 'F 3 '-record (datasheet) in '"
                        + line + "' in file " + self.schematicName)
                # end if
                # endif F 3
            else:
                # Custom Fields, Example:
                # F 4 "C3216-100n-50V" H 8450 6050 60  0001 C CNN "InternalName"

                searchResult = re.search('F +([0-9]+) +"(.*)" +.*"(.*)".*',
                                         line)
                if searchResult:
                    if line_nr > lastExistingFieldLine:
                        lastExistingFieldLine = line_nr

                    fieldNr = int(searchResult.group(1))
                    if fieldNr > maxFieldNr:
                        maxFieldNr = fieldNr

                    fieldValue = searchResult.group(2)
                    fieldName = searchResult.group(3)
                    print(fieldValue)
                    print(fieldName)
                    tempFound = False
                    for anyField in self.fieldList:
                        for Alias in anyField.Aliases:
                            if Alias == fieldName:
                                if fieldFound[anyField] is True:
                                    DT.warning(
                                        "duplicate definition of Field " +
                                        fieldName + " with Alias " + Alias +
                                        " for Component " +
                                        self.getReference() + " in file " +
                                        self.schematicName)
                                fieldFound[anyField] = True
                                tempFound = True
                                cf = ComponentField()
                                cf.setContent(line)
                                cf.relativeLine = line_nr
                                self.propertyList.append(cf)
                                print(fieldName + "added to propertylist ")

                                break
                        if tempFound == True:
                            break
                    if tempFound == True:
                        continue
예제 #5
0
    def ModifyNewSCHFile(self, oldSCHFile, csvFile, savepath):
        # TODO 1: don't call this multiple times, if it is referred multiple times in parent sheets!
        # --> more efficient, avoid possible errors

        # TODO 2: improve this messages: SCH and CSV parts should match
        DT.info("Number of Parts in CSV: " + str(len(csvFile.components)))
        DT.info("Number of Parts in this SCH: " + str(len(self.components)))

        if len(csvFile.components) and len(self.components):

            for i in range(len(csvFile.components)):  #Loop over csv_components
                for p in range(len(
                        self.components)):  #loop over .sch components
                    if csvFile.components[i].reference == self.components[p].getReference() and \
                      self.schematicName ==  csvFile.components[i].getSchematic() and \
                      csvFile.components[i].unit == self.components[p].unit: #if annotation and schematic name match

                        comp = self.components[p]

                        # assign KiCad's default fields:
                        comp.name = csvFile.components[i].name
                        comp.value = csvFile.components[i].value
                        comp.footprint = csvFile.components[i].footprint
                        comp.datasheet = csvFile.components[i].datasheet

                        lineTemplate = ""

                        for ii in range(comp.startPosition, comp.endPosition):
                            line = self.contents[ii]
                            helper = ComponentField(
                            )  # helper for creating 'F x ' records

                            if line[0:2] == 'L ':
                                self.contents[
                                    ii] = 'L ' + comp.name + ' ' + comp.reference + '\n'
                            elif line[0:4] == 'F 1 ':  # component value
                                helper.setContent(line)
                                helper.value = comp.value
                                self.contents[ii] = helper.getContent()

                                lineTemplate = line  # save a template line for newly to be created fields
                            elif line[0:4] == 'F 2 ':  # component footprint
                                helper.setContent(line)
                                helper.value = comp.footprint
                                self.contents[ii] = helper.getContent()
                            elif line[0:4] == 'F 3 ':  # component datasheet
                                helper.setContent(line)
                                helper.value = comp.datasheet
                                self.contents[ii] = helper.getContent()

                        comp.updateAllMatchingFieldValues(
                            csvFile.components[i].propertyList)

                        for property in range(len(comp.propertyList)):
                            if comp.propertyList[property].exists:
                                self.contents[comp.startPosition+comp.propertyList[property].relativeLine] = \
                                 comp.propertyList[property].getContent()
                            else:
                                # otherwise we have to append it
                                self.contents[comp.startPosition+comp.propertyList[property].relativeLine] += \
                                 comp.propertyList[property].getContent()
                        # end for(all properties)
                    # end if components match
                # end for all schematic components
            #end for all csv components

            try:
                f = open(savepath, 'w')
                f.writelines(self.contents)
            except Exception as e:
                print('Error: ' + e)
                return str(e)

            for i in range(len(self.subcircuits)):
                newSavePath = os.path.join(os.path.dirname(savepath),
                                           self.namesOfSubcircuits[i])
                DT.info(newSavePath)
                self.subcircuits[i].ModifyNewSCHFile(0, csvFile, newSavePath)
                #mainFile.ModifyNewSCHFile(0, openCSVFile,savePath):
        else:
            DT.error("No components loaded")