diff --git a/kibot/kicad/v5_sch.py b/kibot/kicad/v5_sch.py index bef5b7ec..1259aa0d 100644 --- a/kibot/kicad/v5_sch.py +++ b/kibot/kicad/v5_sch.py @@ -1029,10 +1029,10 @@ class SchematicComponent(object): field.value = stripped_val def __str__(self): - ref = self.ref + ref = self.ref if self.ref is not None else '??' # Add the sub-part id # How to know if unit 1 is A? - if self.unit > 1: + if self.unit is not None and self.unit > 1: ref += chr(ord('A')+self.unit-1) if self.name == self.value: return '{} ({})'.format(ref, self.name) diff --git a/kibot/kicad/v6_sch.py b/kibot/kicad/v6_sch.py index 8619113f..daf5f2bd 100644 --- a/kibot/kicad/v6_sch.py +++ b/kibot/kicad/v6_sch.py @@ -10,9 +10,10 @@ Currently oriented to collect the components for the BoM and create a variant of Documentation: https://dev-docs.kicad.org/en/file-formats/sexpr-schematic/ """ # Encapsulate file/line +from collections import OrderedDict +from copy import deepcopy import os import re -from collections import OrderedDict from ..gs import GS from .. import log from ..misc import W_NOLIB, W_UNKFLD, W_MISSCMP @@ -30,13 +31,32 @@ version = None KICAD_7_VER = 20230121 SHEET_FILE = {'Sheet file', 'Sheetfile'} SHEET_NAME = {'Sheet name', 'Sheetname'} -UUID_fake = 0 -def get_global_uuid(): - global UUID_fake - UUID_fake += 1 - return str(UUID_fake) +class UUID_Validator(object): + known_UUIDs = set() + + def reset(): + UUID_Validator.known_UUIDs = set() + + # TODO: Accept "None"? + def validate(uuid): + no_collision = True + if uuid in UUID_Validator.known_UUIDs: + # logger.error(f"Collision {uuid}") + uuid_comps = uuid.split('-') + assert len(uuid_comps) == 5 and len(uuid_comps[0]) == 8 + variable = int(uuid_comps[0], 16)+1 + uuid = "{0:08x}".format(variable % 0x100000000)+'-'+'-'.join(uuid_comps[1:]) + # Solve collision + while uuid in UUID_Validator.known_UUIDs: + variable = variable + 1 + uuid = "{0:08x}".format(variable % 0x100000000)+'-'+'-'.join(uuid_comps[1:]) + # logger.error(f"New UUID {uuid}") + no_collision = False + UUID_Validator.known_UUIDs.add(uuid) + # logger.warning(f"Adding {uuid}") + return uuid, no_collision class PointXY(object): @@ -315,21 +335,20 @@ class DrawArcV6(object): elif i_type == 'fill': arc.fill = Fill.parse(i) elif i_type == 'uuid': - arc.uuid = _get_uuid(items, c+1, 'arc') + arc.uuid = get_uuid(items, c+1, 'arc') else: raise SchError('Unknown arc attribute `{}`'.format(i)) arc.box = Box([arc.start, arc.mid, arc.end]) return arc - def write(self, cross): + def write(self): data = [_symbol('start', [self.start.x, self.start.y])] data.append(_symbol('mid', [self.mid.x, self.mid.y])) data.append(_symbol('end', [self.end.x, self.end.y])) data.append(Sep()) data.extend([self.stroke.write(), Sep()]) data.extend([self.fill.write(), Sep()]) - if self.uuid is not None and not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) return _symbol('arc', data) @@ -356,7 +375,7 @@ class DrawCircleV6(object): elif i_type == 'fill': circle.fill = Fill.parse(i) elif i_type == 'uuid': - circle.uuid = _get_uuid(items, c+1, 'circle') + circle.uuid = get_uuid(items, c+1, 'circle') else: raise SchError('Unknown circle attribute `{}`'.format(i)) p1 = PointXY(circle.center.x-circle.radius, circle.center.x-circle.radius) @@ -364,14 +383,13 @@ class DrawCircleV6(object): circle.box = Box([p1, p2]) return circle - def write(self, cross): + def write(self): data = [_symbol('center', [self.center.x, self.center.y])] data.append(_symbol('radius', [self.radius])) data.append(Sep()) data.extend([self.stroke.write(), Sep()]) data.extend([self.fill.write(), Sep()]) - if self.uuid is not None and not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) return _symbol('circle', data) @@ -398,20 +416,19 @@ class DrawRectangleV6(object): elif i_type == 'fill': rectangle.fill = Fill.parse(i) elif i_type == 'uuid': - rectangle.uuid = _get_uuid(items, c+1, 'rectangle') + rectangle.uuid = get_uuid(items, c+1, 'rectangle') else: raise SchError('Unknown rectangle attribute `{}`'.format(i)) rectangle.box = Box([rectangle.start, rectangle.end]) return rectangle - def write(self, cross=False): + def write(self): data = [_symbol('start', [self.start.x, self.start.y])] data.append(_symbol('end', [self.end.x, self.end.y])) data.append(Sep()) data.extend([self.stroke.write(), Sep()]) data.extend([self.fill.write(), Sep()]) - if self.uuid is not None and not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) return _symbol('rectangle', data) @@ -439,7 +456,7 @@ class DrawCurve(object): curve.box = Box(curve.points) return curve - def write(self, _=False): + def write(self): points = [Sep()] for p in self.points: points.append(_symbol('xy', [p.x, p.y])) @@ -473,7 +490,7 @@ class DrawPolyLine(object): line.box = Box(line.points) return line - def write(self, _=False): + def write(self): points = [Sep()] for p in self.points: points.append(_symbol('xy', [p.x, p.y])) @@ -500,7 +517,7 @@ class DrawTextV6(object): text.effects = _get_effects(items, 3, 'text') return text - def write(self, _=False): + def write(self): data = [self.text, _symbol('at', [self.x, self.y, self.ang]), Sep()] data.extend([self.effects.write(), Sep()]) return _symbol('text', data) @@ -852,7 +869,7 @@ class LibComponent(object): sdata.extend([o.write(), Sep()]) s.cross_box = None - def write(s, cross=False): + def write(s, cross): lib_id = s.lib_id if cross: # Fill the cross_box of our sub/units @@ -883,7 +900,7 @@ class LibComponent(object): sdata.extend([fdata, Sep()]) # Graphics for g in s.draw: - sdata.extend([g.write(cross), Sep()]) + sdata.extend([g.write(), Sep()]) s.write_cross(sdata) # Pins for p in s.pins: @@ -942,7 +959,7 @@ class SchematicComponentV6(SchematicComponent): self.mirror = None self.convert = None self.pin_alternates = {} - self.uuid = get_global_uuid() + self.uuid = None # KiCad v7: # Instances classified by project (v7) self.projects = None @@ -988,7 +1005,7 @@ class SchematicComponentV6(SchematicComponent): def load_pin(self, i, name): pin_name = _check_str(i, 1, name + 'pin name') - pin_uuid = _get_uuid(i, 2, name) + pin_uuid = get_uuid(i, 2, name) self.pins[pin_name] = pin_uuid if len(i) > 3: # Not documented @@ -1065,7 +1082,9 @@ class SchematicComponentV6(SchematicComponent): # Not documented comp.fields_autoplaced = True elif i_type == 'uuid': - comp.uuid = _check_symbol(i, 1, name + ' uuid') + # Ensure we have a unique UUID + comp.uuid_ori = _check_symbol(i, 1, name + ' uuid') + comp.uuid, _ = UUID_Validator.validate(comp.uuid_ori) # SYMBOL_PROPERTIES... elif i_type == 'property': field = SchematicFieldV6.parse(i, field_id) @@ -1088,12 +1107,16 @@ class SchematicComponentV6(SchematicComponent): elif i_type == 'instances': comp.load_instances(i) # We should get an instance for us - ins = comp.all_instances.get(parent.get_full_path()) + p_path = parent.get_full_path() + ins = comp.all_instances.get(p_path) if ins is None: - raise SchError('Missing {} symbol instance for `{}`'.format(comp.name, parent.get_full_path())) + raise SchError('Missing {} symbol instance for `{}`'.format(comp.name, p_path)) + # Memorize its path (v7 style, with parent) + comp.p_path_ori = p_path + comp.p_path = parent.get_full_path(False) # Translate the instance to the v6 format (remove UUID for / and add the component UUID) v6_ins = SymbolInstance() - v6_ins.path = os.path.join('/', '/'.join(ins.path.split('/')[2:]), comp.uuid) + v6_ins.path = os.path.join('/', '/'.join(ins.path.split('/')[2:]), comp.uuid_ori) v6_ins.reference = ins.reference v6_ins.unit = ins.unit # Add to the root symbol_instances, so we reconstruct it @@ -1102,16 +1125,17 @@ class SchematicComponentV6(SchematicComponent): raise SchError('Unknown component attribute `{}`'.format(i)) if not lib_id_found or not at_found: raise SchError("Component missing 'lib_id' and/or 'at'") - # Fake 'Part' field field = SchematicFieldV6() field.name = 'part' field.value = comp.name field.number = -1 comp.add_field(field) + # Memorize the current path, used for expanded hierarchy + comp.path = parent.sheet_path return comp - def write(self, cross=False): + def write(self, cross): lib_id = self.lib_id is_crossed = not(self.fitted or not self.included) native_cross = GS.ki7 and GS.global_cross_using_kicad @@ -1139,16 +1163,14 @@ class SchematicComponentV6(SchematicComponent): if self.fields_autoplaced: data.append(_symbol('fields_autoplaced')) data.append(Sep()) - if not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) for f in self.fields: d = f.write() if d: data.extend([d, Sep()]) for k, v in self.pins.items(): pin_data = [k] - if not cross: - pin_data.extend([_symbol('uuid', [Symbol(v)])]) + add_uuid(pin_data, v, no_sep=True) alternate = self.pin_alternates.get(k, None) if alternate: pin_data.append(_symbol('alternate', [alternate])) @@ -1156,8 +1178,19 @@ class SchematicComponentV6(SchematicComponent): if self.projects is not None: prj_data = [Sep()] for prj, ins in self.projects: + if cross and prj != self.project: + # For the expanded hierarchy we save only this project + continue ins_data = [prj, Sep()] for i in ins: + if cross: + if i.path == self.p_path_ori: + # Adjust the instance for the expanded hierarchy + i = deepcopy(i) + i.path = self.p_path + else: + # Don't store bogus instances + continue ins_data.extend([i.write(), Sep()]) prj_data.extend([_symbol('project', ins_data), Sep()]) data.extend([_symbol('instances', prj_data), Sep()]) @@ -1171,8 +1204,14 @@ def _get_uuid(items, pos, where): return _check_symbol(values, 1, where + ' uuid') -def add_uuid(data, cross, uuid, no_sep=False): - if not cross and uuid: +def get_uuid(items, pos, where): + uuid = _get_uuid(items, pos, where) + uuid, _ = UUID_Validator.validate(uuid) + return uuid + + +def add_uuid(data, uuid, no_sep=False): + if uuid: if no_sep: data.append(_symbol('uuid', [Symbol(uuid)])) else: @@ -1188,14 +1227,14 @@ class Junction(object): jun.pos_x, jun.pos_y, jun.ang = _get_at(items, 1, 'junction') jun.diameter = _check_symbol_float(items, 2, 'junction', 'diameter') jun.color = Color.parse(items[3]) - jun.uuid = _get_uuid(items, 4, 'junction') + jun.uuid = get_uuid(items, 4, 'junction') return jun - def write(self, cross=False): + def write(self): data = [_symbol('at', [self.pos_x, self.pos_y]), _symbol('diameter', [self.diameter]), self.color.write(), Sep()] - add_uuid(data, cross, self.uuid) + add_uuid(data, self.uuid) return _symbol('junction', data) @@ -1220,12 +1259,12 @@ class NoConnect(object): _check_len_total(items, 2, 'no_connect') nocon = NoConnect() nocon.pos_x, nocon.pos_y, nocon.ang = _get_at(items, 1, 'no connect') - nocon.uuid = _get_uuid(items, 2, 'no connect') + nocon.uuid = get_uuid(items, 2, 'no connect') return nocon - def write(self, cross=False): + def write(self): data = [_symbol('at', [self.pos_x, self.pos_y])] - add_uuid(data, cross, self.uuid, no_sep=True) + add_uuid(data, self.uuid, no_sep=True) return _symbol('no_connect', data) @@ -1238,14 +1277,14 @@ class BusEntry(object): buse.pos_x, buse.pos_y, buse.ang = _get_at(items, 1, 'bus entry') buse.size = _get_size(items, 2, 'bus entry') buse.stroke = Stroke.parse(items[3]) - buse.uuid = _get_uuid(items, 4, 'bus entry') + buse.uuid = get_uuid(items, 4, 'bus entry') return buse - def write(self, cross=False): + def write(self): data = [_symbol('at', [self.pos_x, self.pos_y]), _symbol('size', [self.size.x, self.size.y]), Sep(), self.stroke.write(), Sep()] - add_uuid(data, cross, self.uuid) + add_uuid(data, self.uuid) return _symbol('bus_entry', data) @@ -1258,13 +1297,13 @@ class SchematicWireV6(object): wire.type = name # wire, bus, polyline wire.points = _get_points(items[1]) wire.stroke = Stroke.parse(items[2]) - wire.uuid = _get_uuid(items, 3, name) + wire.uuid = get_uuid(items, 3, name) return wire - def write(self, cross=False): + def write(self): points = [_symbol('xy', [p.x, p.y]) for p in self.points] data = [_symbol('pts', points), Sep(), self.stroke.write(), Sep()] - add_uuid(data, cross, self.uuid) + add_uuid(data, self.uuid) return _symbol(self.type, data) @@ -1280,7 +1319,7 @@ class SchematicBitmapV6(object): if i_type == 'scale': bmp.scale = _check_symbol_float(items, c+2, 'image', 'scale') elif i_type == 'uuid': - bmp.uuid = _get_uuid(items, c+2, 'image') + bmp.uuid = get_uuid(items, c+2, 'image') elif i_type == 'data': values = _check_symbol_value(items, c+2, 'image data', 'data') bmp.data = [_check_symbol(values, i+1, 'image data') for i, d in enumerate(values[1:])] @@ -1288,14 +1327,13 @@ class SchematicBitmapV6(object): raise SchError('Unknown symbol attribute `{}`'.format(i)) return bmp - def write(self, cross=False): + def write(self): d = [] for v in self.data: d.append(Symbol(v)) d.append(Sep()) data = [_symbol('at', [self.pos_x, self.pos_y]), Sep()] - if not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) data.extend([_symbol('data', [Sep()] + d), Sep()]) return _symbol('image', data) @@ -1314,7 +1352,7 @@ class Text(object): elif i_type == 'effects': text.effects = _get_effects(items, c+2, name) elif i_type == 'uuid': - text.uuid = _get_uuid(items, c+2, name) + text.uuid = get_uuid(items, c+2, name) elif i_type == 'exclude_from_sim': # KiCad 7.99 text.exclude_from_sim = _get_yes_no(i, 1, i_type) @@ -1322,14 +1360,13 @@ class Text(object): raise SchError('Unknown symbol attribute `{}`'.format(i)) return text - def write(self, cross=False): + def write(self): data = [self.text] if self.exclude_from_sim is not None: data.append(_symbol('exclude_from_sim', [Symbol(NO_YES[self.exclude_from_sim])])) data.extend([_symbol('at', [self.pos_x, self.pos_y, self.ang]), Sep(), self.effects.write(), Sep()]) - if not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) return _symbol(self.name, data) @@ -1344,17 +1381,16 @@ class TextBox(object): text.stroke = Stroke.parse(items[4]) text.fill = Fill.parse(items[5]) text.effects = _get_effects(items, 6, name) - text.uuid = _get_uuid(items, 7, name) + text.uuid = get_uuid(items, 7, name) return text - def write(self, cross=False): + def write(self): data = [self.text, Sep(), _symbol('at', [self.pos_x, self.pos_y, self.ang]), _symbol('size', [self.size.x, self.size.y]), Sep(), self.stroke.write(), Sep(), self.fill.write(), Sep(), self.effects.write(), Sep()] - if not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) return _symbol(self.name, data) @@ -1389,7 +1425,7 @@ class GlobalLabel(object): elif i_type == 'effects': label.effects = FontEffects.parse(i) elif i_type == 'uuid': - label.uuid = _get_uuid(items, c+2, label.name) + label.uuid = get_uuid(items, c+2, label.name) elif i_type == 'property': label.properties.append(SchematicFieldV6.parse(i, field_id)) field_id += 1 @@ -1397,7 +1433,7 @@ class GlobalLabel(object): raise SchError('Unknown {} attribute `{}`'.format(label.name, i)) return label - def write(self, cross=False): + def write(self): data = [self.text] if self.length is not None: data.append(_symbol('length', [self.length])) @@ -1409,8 +1445,7 @@ class GlobalLabel(object): if self.effects is not None: data.extend([Sep(), self.effects.write()]) data.append(Sep()) - if not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) for p in self.properties: data.extend([p.write(), Sep()]) return _symbol(self.name, data) @@ -1447,16 +1482,15 @@ class HSPin(object): pin.type = _check_symbol(items, 2, name+' type') pin.pos_x, pin.pos_y, pin.ang = _get_at(items, 3, name) pin.effects = _get_effects(items, 4, name) - pin.uuid = _get_uuid(items, 5, name) + pin.uuid = get_uuid(items, 5, name) return pin - def write(self, cross=False): + def write(self): data = [self.name, Symbol(self.type), _symbol('at', [self.pos_x, self.pos_y, self.ang]), Sep(), self.effects.write(), Sep()] - if not cross: - data.extend([_symbol('uuid', [Symbol(self.uuid)]), Sep()]) + add_uuid(data, self.uuid) return _symbol('pin', data) @@ -1527,7 +1561,8 @@ class Sheet(object): elif i_type == 'fill': sheet.fill = Fill.parse(i) elif i_type == 'uuid': - sheet.uuid = _get_uuid(items, c+1, 'sheet') + sheet.uuid_ori = _get_uuid(items, c+1, 'sheet') + sheet.uuid, _ = UUID_Validator.validate(sheet.uuid_ori) elif i_type == 'property': field = SchematicFieldV6.parse(i, field_id) field_id += 1 @@ -1552,28 +1587,33 @@ class Sheet(object): self.sheet = sheet parent_dir = os.path.dirname(parent_file) sheet.sheet_path = os.path.join(parent_obj.sheet_path, self.uuid) + sheet.sheet_path_ori = os.path.join(parent_obj.sheet_path, self.uuid_ori) sheet.sheet_path_h = os.path.join(parent_obj.sheet_path_h, self.name) - parent_obj.sheet_paths[sheet.sheet_path] = sheet + parent_obj.sheet_paths[sheet.sheet_path_ori] = sheet sheet.load(os.path.join(parent_dir, self.file), project, parent_obj) # self.sheet_paths if self.projects is not None: # KiCad v7 sheet pages are here - page = self.all_instances.get(parent_obj.get_full_path()) + p_path = parent_obj.get_full_path() + page = self.all_instances.get(p_path) if page is None: - raise SchError('Missing sheet instance for `{}`'.format(parent_obj.get_full_path())) + raise SchError('Missing sheet instance for `{}`'.format(p_path)) else: sheet.sheet = page parent_obj.all_sheets.append(sheet) + # Memorize its path + self.p_path_ori = p_path + self.p_path = parent_obj.get_full_path(False) return sheet - def write(self, cross=False): + def write(self, cross): data = [_symbol('at', [self.pos_x, self.pos_y]), _symbol('size', [self.w, self.h])] if self.fields_autoplaced: data.append(_symbol('fields_autoplaced', [])) data.extend([Sep(), self.stroke.write(), Sep(), - self.fill.write(), Sep(), - _symbol('uuid', [Symbol(self.uuid)]), Sep()]) + self.fill.write(), Sep()]) + add_uuid(data, self.uuid) for p in self.properties: change_file = cross and p.name in SHEET_FILE if change_file: @@ -1582,12 +1622,24 @@ class Sheet(object): if change_file: p.value = self.file for p in self.pins: - data.extend([p.write(cross), Sep()]) + data.extend([p.write(), Sep()]) if self.projects is not None: prj_data = [Sep()] + sheet = self.sheet for prj, ins in self.projects: + if cross and prj != sheet.project: + # For the expanded hierarchy we save only this project + continue ins_data = [prj, Sep()] for i in ins: + if cross: + if i.path == self.p_path_ori: + # Adjust the instance for the expanded hierarchy + i = deepcopy(i) + i.path = self.p_path + else: + # Don't store bogus instances + continue ins_data.extend([i.write(), Sep()]) prj_data.extend([_symbol('project', ins_data), Sep()]) data.extend([_symbol('instances', prj_data), Sep()]) @@ -1768,13 +1820,13 @@ class SchematicV6(Schematic): return data return [Sep(), Sep(), _symbol('title_block', [Sep()]+data)] - def write_lib_symbols(self, cross=False): + def write_lib_symbols(self, cross): if GS.ki7 and GS.global_cross_using_kicad: # KiCad 7 can cross it by itself cross = False data = [Sep()] for s in self.lib_symbols: - data.extend([s.write(), Sep()]) + data.extend([s.write(cross), Sep()]) if cross: data.extend([s.write(cross), Sep()]) return [Sep(), Sep(), _symbol('lib_symbols', data), Sep()] @@ -1784,6 +1836,7 @@ class SchematicV6(Schematic): global version version = self.version cross = dest_dir is not None + # cross = False if base_sheet is None: # We are the base sheet base_sheet = self @@ -1816,61 +1869,72 @@ class SchematicV6(Schematic): sch.append(_symbol('generator', [Symbol(self.generator)])) sch.append(Sep()) sch.append(Sep()) - if not cross or base_sheet == self: - # The "cross" (or variant) mode expands the hierarchy - # So we avoid using UUIDs to avoid repeating them - # The only UUIDs really needed are the ones used for the "path" for component instances - # This includes the first page UUID. - sch.append(_symbol('uuid', [Symbol(self.uuid)])) + add_uuid(sch, self.uuid, no_sep=True) sch.extend(self.write_paper()) sch.extend(self.write_title_block()) sch.extend(self.write_lib_symbols(cross)) # Bus aliases _add_items(self.bus_alias, sch) # Connections (aka Junctions) - _add_items(self.junctions, sch, pre_sep=(len(self.bus_alias) == 0), cross=cross) + _add_items(self.junctions, sch, pre_sep=(len(self.bus_alias) == 0)) # No connect - _add_items(self.no_conn, sch, cross=cross) + _add_items(self.no_conn, sch) # Bus entry - _add_items(self.bus_entry, sch, cross=cross) + _add_items(self.bus_entry, sch) # Lines (wire, bus and polyline) if self.wires: old_type = 'none' for e in self.wires: if e.type != old_type and old_type != 'wire': sch.append(Sep()) - sch.append(e.write(cross)) + sch.append(e.write()) old_type = e.type sch.append(Sep()) # Arcs - _add_items(self.arcs, sch, cross=cross) + _add_items(self.arcs, sch) # Circles - _add_items(self.circles, sch, cross=cross) + _add_items(self.circles, sch) # Rectangles - _add_items(self.rectangles, sch, cross=cross) + _add_items(self.rectangles, sch) # Images - _add_items(self.bitmaps, sch, cross=cross) + _add_items(self.bitmaps, sch) # Text Boxes - _add_items(self.text_boxes, sch, cross=cross) + _add_items(self.text_boxes, sch) # Texts - _add_items(self.texts, sch, cross=cross, pre_sep=False) + _add_items(self.texts, sch, pre_sep=False) # Labels - _add_items(self.labels, sch, cross=cross) + _add_items(self.labels, sch) # Global Labels - _add_items(self.glabels, sch, cross=cross) + _add_items(self.glabels, sch) # Hierarchical Labels - _add_items(self.hlabels, sch, cross=cross) + _add_items(self.hlabels, sch) # Net Class Flags - _add_items(self.net_class_flags, sch, cross=cross) + _add_items(self.net_class_flags, sch) # Symbols _add_items(self.symbols, sch, sep=True, cross=cross) # Sheets _add_items(self.sheets, sch, sep=True, cross=cross) # Sheet instances - _add_items_list('sheet_instances', self.sheet_instances, sch) + instances = self.sheet_instances + if cross: + # We are saving a expanded hierarchy, so we must fix the instances + instances = deepcopy(self.sheet_instances) + for ins in instances: + ins.path = self.sheet_paths[ins.path].sheet_path + _add_items_list('sheet_instances', instances, sch) # Symbol instances if version < KICAD_7_VER and base_sheet == self: - _add_items_list('symbol_instances', self.symbol_instances, sch) + instances = self.symbol_instances + if cross: + # We are saving a expanded hierarchy, so we must fix the instances + instances = deepcopy(self.symbol_instances) + for s in instances: + c = s.component + if c.uuid != c.uuid_ori: + # UUID changed to make it different + # s.path = os.path.join(os.path.dirname(s.path), c.uuid) + s.path = os.path.join(c.path, c.uuid) + _add_items_list('symbol_instances', instances, sch) logger.debug('Saving schematic: `{}`'.format(fname)) # Keep a back-up of existing files if os.path.isfile(fname): @@ -1894,7 +1958,7 @@ class SchematicV6(Schematic): Is used to save a variant, where we avoid sharing instance data """ # Store it in the UUID -> name # Used to create a human readable sheet path - self.sheet_names[os.path.join(self.sheet_path, sch.uuid)] = os.path.join(self.sheet_path_h, sch.name) + self.sheet_names[os.path.join(self.sheet_path_ori, sch.uuid_ori)] = os.path.join(self.sheet_path_h, sch.name) # Eliminate subdirs file = sch.file.replace('/', '_') fparts = os.path.splitext(file) @@ -1909,30 +1973,43 @@ class SchematicV6(Schematic): self.title_ori = title return old_title - def get_full_path(self): + def get_full_path(self, ori=True): """ Path using the UUID of the root. Used by v7 """ path = '/'+self.root_sheet.uuid # Avoid returning /UUID/ if self.sheet_path != '/': - path += self.sheet_path + path += self.sheet_path_ori if ori else self.sheet_path return path + def debug_instances(self): + """ Debug for the expanded hierarchy """ + logger.debug("Collected symbol instances") + for s in sorted(self.symbol_instances, key=lambda x: x.path): + logger.debug(f"- {s.path} -> {s.reference}") + logger.debug("Collected sheet paths") + for p, s in self.sheet_paths.items(): + logger.debug(f"- {p}") + for sy, c in s.symbol_uuids.items(): + logger.debug(f" - {sy} -> {c}") + def load(self, fname, project, parent=None): # noqa: C901 """ Load a v6.x KiCad Schematic. The caller must be sure the file exists. Only the schematics are loaded not the libs. """ logger.debug("Loading sheet from "+fname) + extra_debug = GS.debug_level >= 3 if parent is None: self.fields = ['part'] self.fields_lc = set(self.fields) self.sheet_paths = {'/': self} self.lib_symbol_names = {} - self.sheet_path = '/' + self.sheet_path = self.sheet_path_ori = '/' self.sheet_path_h = '/' self.sheet_names = {} self.all_sheets = [] self.root_sheet = self self.symbol_instances = [] + UUID_Validator.reset() else: self.fields = parent.fields self.fields_lc = parent.fields_lc @@ -1990,7 +2067,9 @@ class SchematicV6(Schematic): elif e_type == 'generator': self.generator = _check_symbol(e, 1, e_type) elif e_type == 'uuid': - self.id = self.uuid = _check_symbol(e, 1, e_type) + self.uuid_ori = _check_symbol(e, 1, e_type) + uuid, _ = UUID_Validator.validate(self.uuid_ori) + self.id = self.uuid = uuid elif e_type == 'paper': self.paper = _check_str(e, 1, e_type) index = 2 @@ -2041,8 +2120,10 @@ class SchematicV6(Schematic): self.net_class_flags.append(NetClassFlag.parse(e)) elif e_type == 'symbol': obj = SchematicComponentV6.load(e, self.project, self) + if extra_debug: + logger.debug(f"- Loaded {obj} [id {id(obj)}] UUID {obj.uuid} original UUID {obj.uuid_ori}") self.symbols.append(obj) - self.symbol_uuids[obj.uuid] = obj + self.symbol_uuids[os.path.join(self.sheet_path_ori, obj.uuid_ori)] = obj elif e_type == 'sheet': obj = Sheet.parse(e) self.sheets.append(obj) @@ -2072,16 +2153,23 @@ class SchematicV6(Schematic): if sheet: sheet.sheet = i.page self.all_sheets.append(sheet) + # Debug for the expanded hierarchy + if extra_debug: + self.debug_instances() # Create the components list for s in self.symbol_instances: # Get a copy of the original symbol path = os.path.dirname(s.path) - sheet = self.sheet_paths[path] - comp_uuid = os.path.basename(s.path) try: - comp = sheet.symbol_uuids[comp_uuid] + sheet = self.sheet_paths[path] except KeyError: - logger.error(f"Error looking for {comp_uuid}") + logger.error(f"Error looking for sheet {path}") + logger.error(f"Available UUIDs {sheet.sheet_paths}") + raise + try: + comp = sheet.symbol_uuids[s.path] + except KeyError: + logger.error(f"Error looking for component {s.path}") logger.error(f"Available UUIDs {sheet.symbol_uuids}") raise s.component = comp @@ -2095,7 +2183,7 @@ class SchematicV6(Schematic): comp.set_footprint(s.footprint) comp.sheet_path = path comp.sheet_path_h = self.path_to_human(path) - comp.id = comp_uuid + comp.id = comp.uuid if s.reference[-1] == '?': comp.annotation_error = True self.annotation_error = True @@ -2110,6 +2198,8 @@ class SchematicV6(Schematic): comp.desc = lib_symbol.get_field_value('ki_description') # Now we have all the data comp._validate() + if extra_debug: + logger.debug(f"{s.path} -> {s.reference} -> {id(comp)} {comp.uuid}") # Add it to the list self.components.append(comp) self.comps_data = self.lib_symbol_names diff --git a/tests/board_samples/kicad_6/shared_page_value_change/filter.kicad_sch b/tests/board_samples/kicad_6/shared_page_value_change/filter.kicad_sch new file mode 100644 index 00000000..37778835 --- /dev/null +++ b/tests/board_samples/kicad_6/shared_page_value_change/filter.kicad_sch @@ -0,0 +1,223 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid b1187436-c896-448a-926e-98e9b75df996) + + (paper "A4") + + (lib_symbols + (symbol "Device:C" (pin_numbers hide) (pin_names (offset 0.254)) (in_bom yes) (on_board yes) + (property "Reference" "C" (id 0) (at 0.635 2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "C" (id 1) (at 0.635 -2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (id 2) (at 0.9652 -3.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "cap capacitor" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Unpolarized capacitor" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "C_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "C_0_1" + (polyline + (pts + (xy -2.032 -0.762) + (xy 2.032 -0.762) + ) + (stroke (width 0.508) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy -2.032 0.762) + (xy 2.032 0.762) + ) + (stroke (width 0.508) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "C_1_1" + (pin passive line (at 0 3.81 270) (length 2.794) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -3.81 90) (length 2.794) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "R" (id 0) (at 2.032 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "R" (id 1) (at 0 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at -1.778 0 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "R res resistor" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Resistor" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "R_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "R_0_1" + (rectangle (start -1.016 -2.54) (end 1.016 2.54) + (stroke (width 0.254) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "R_1_1" + (pin passive line (at 0 3.81 270) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -3.81 90) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "power:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "#PWR" (id 0) (at 0 -6.35 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 0 -3.81 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "global power" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Power symbol creates a global label with name \"GND\" , ground" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "GND_0_1" + (polyline + (pts + (xy 0 0) + (xy 0 -1.27) + (xy 1.27 -1.27) + (xy 0 -2.54) + (xy -1.27 -1.27) + (xy 0 -1.27) + ) + (stroke (width 0) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "GND_1_1" + (pin power_in line (at 0 0 270) (length 0) hide + (name "GND" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + ) + ) + ) + + (junction (at 115.57 63.5) (diameter 0) (color 0 0 0 0) + (uuid f0903ccd-ddaa-4fd7-a697-981f2d0f9397) + ) + + (wire (pts (xy 115.57 63.5) (xy 115.57 68.58)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 2d4790c8-46d7-4a9f-937f-bf3b2d8efada) + ) + (wire (pts (xy 88.9 63.5) (xy 96.52 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 39aed1ce-6762-43f2-82fa-7c9cbbad1bbd) + ) + (wire (pts (xy 115.57 76.2) (xy 115.57 82.55)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 3bc07038-b2b5-45e0-8cd1-21ab40e6b75f) + ) + (wire (pts (xy 115.57 63.5) (xy 127 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 5ed7720b-4ec3-4927-aa9a-3201ed3eca32) + ) + (wire (pts (xy 104.14 63.5) (xy 115.57 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 6660fa40-6f3f-4ef8-8139-af510388e89f) + ) + + (hierarchical_label "OUT" (shape output) (at 127 63.5 0) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 38c07dda-cb98-4962-b63e-de8104ed14d0) + ) + (hierarchical_label "IN" (shape input) (at 88.9 63.5 180) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid fef124b4-a5f0-4dd5-80b1-3800774fbd73) + ) + + (symbol (lib_id "power:GND") (at 115.57 82.55 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 2008b722-6f66-498d-8afb-79e172fe202d) + (property "Reference" "#PWR?" (id 0) (at 115.57 88.9 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 115.57 87.63 0)) + (property "Footprint" "" (id 2) (at 115.57 82.55 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 115.57 82.55 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 428fe857-2241-4f1f-b4de-cfb744d6d47c)) + ) + + (symbol (lib_id "Device:C") (at 115.57 72.39 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 3316c32a-0fe0-447f-ad05-e8a774318855) + (property "Reference" "C1" (id 0) (at 119.38 71.1199 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "150p" (id 1) (at 119.38 73.6599 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (id 2) (at 116.5352 76.2 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 115.57 72.39 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 2a7f634a-eeee-4d03-a085-23c5053ac8fc)) + (pin "2" (uuid 17af8374-6edb-4cba-b417-78ee4ed8db8e)) + ) + + (symbol (lib_id "Device:R") (at 100.33 63.5 90) (unit 1) + (in_bom yes) (on_board yes) + (uuid 6e279b82-cec2-44a1-9e20-451a25fb9868) + (property "Reference" "R1" (id 0) (at 100.33 58.42 90)) + (property "Value" "100k" (id 1) (at 100.33 60.96 90)) + (property "Footprint" "" (id 2) (at 100.33 65.278 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 100.33 63.5 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid b11eb219-0980-4284-98f4-0c978028fc3f)) + (pin "2" (uuid dcb1e8c5-0fc5-4595-83da-d83fbe9a9876)) + ) +) diff --git a/tests/board_samples/kicad_6/shared_page_value_change/value_change.kicad_sch b/tests/board_samples/kicad_6/shared_page_value_change/value_change.kicad_sch new file mode 100644 index 00000000..54bfb71b --- /dev/null +++ b/tests/board_samples/kicad_6/shared_page_value_change/value_change.kicad_sch @@ -0,0 +1,321 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid 2edf3773-c8c4-44a8-b0bd-a7fa9d597fb5) + + (paper "A4") + + (lib_symbols + (symbol "Connector:Conn_01x03_Male" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes) + (property "Reference" "J" (id 0) (at 0 5.08 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Conn_01x03_Male" (id 1) (at 0 -5.08 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "connector" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Conn_01x03_Male_1_1" + (polyline + (pts + (xy 1.27 -2.54) + (xy 0.8636 -2.54) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 0) + (xy 0.8636 0) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 2.54) + (xy 0.8636 2.54) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start 0.8636 -2.413) (end 0 -2.667) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 0.127) (end 0 -0.127) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 2.667) (end 0 2.413) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (pin passive line (at 5.08 2.54 180) (length 3.81) + (name "Pin_1" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 0 180) (length 3.81) + (name "Pin_2" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -2.54 180) (length 3.81) + (name "Pin_3" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "power:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "#PWR" (id 0) (at 0 -6.35 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 0 -3.81 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "global power" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Power symbol creates a global label with name \"GND\" , ground" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "GND_0_1" + (polyline + (pts + (xy 0 0) + (xy 0 -1.27) + (xy 1.27 -1.27) + (xy 0 -2.54) + (xy -1.27 -1.27) + (xy 0 -1.27) + ) + (stroke (width 0) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "GND_1_1" + (pin power_in line (at 0 0 270) (length 0) hide + (name "GND" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + ) + ) + ) + + + (wire (pts (xy 148.59 102.87) (xy 153.67 102.87)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 014f4a41-f96a-440f-a7df-bff9cc8b584f) + ) + (wire (pts (xy 153.67 102.87) (xy 153.67 91.44)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 318d1a1c-c645-4371-9840-4addf9815390) + ) + (wire (pts (xy 119.38 91.44) (xy 119.38 102.87)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 4cf82e5c-3b1e-4592-86e1-831746fe0a50) + ) + (wire (pts (xy 148.59 88.9) (xy 165.1 88.9)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 6b782584-bbda-4063-871c-baa87b2e3a3a) + ) + (wire (pts (xy 119.38 102.87) (xy 124.46 102.87)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 9344469f-8a37-4d7b-b4fd-e1dff551e5c5) + ) + (wire (pts (xy 107.95 91.44) (xy 119.38 91.44)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 985d532a-ca7f-4177-9f5a-723e7cc92a38) + ) + (wire (pts (xy 162.56 93.98) (xy 162.56 96.52)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 9a66c46b-3815-4a1c-9c95-54dda20ca51a) + ) + (wire (pts (xy 110.49 93.98) (xy 110.49 96.52)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 9efc67a5-596f-4b7b-b65d-d36188443244) + ) + (wire (pts (xy 107.95 93.98) (xy 110.49 93.98)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid a16cd396-ad8f-4027-9a33-6323720f1d9e) + ) + (wire (pts (xy 165.1 93.98) (xy 162.56 93.98)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid b7ed1d31-2d13-4472-92b9-c2b0cfd3e355) + ) + (wire (pts (xy 153.67 91.44) (xy 165.1 91.44)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid ce8e6896-c0d6-441f-8ddd-cb3f340d1723) + ) + (wire (pts (xy 107.95 88.9) (xy 124.46 88.9)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid e82f25fe-3e57-41fb-8fba-6cb01942af70) + ) + + (text "Test for sheet reuse. Not a real life circuit.\nWe have two filters A and B.\nFilter A is 10.6 kHz LPF\nBut we want filter B to be 7.3 kHz, not 10.6 kHz\nKiCad won't allow it because R1 must be exactly the same as R2 and C1 identical to C2.\nWe'll use KiBot to force this.\nWe'll change C2 from 150 pF to 220 pF" + (at 15.24 57.15 0) + (effects (font (size 3.8 3.8)) (justify left bottom)) + (uuid 05df6345-718c-4e3b-b675-d4c4d21bec79) + ) + + (symbol (lib_id "power:GND") (at 162.56 96.52 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 431ea6a1-54ca-474a-94e5-019b2198369c) + (property "Reference" "#PWR?" (id 0) (at 162.56 102.87 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 162.56 101.6 0)) + (property "Footprint" "" (id 2) (at 162.56 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 162.56 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 76034050-bfce-465a-b3ca-155ba43fbbb0)) + ) + + (symbol (lib_id "Connector:Conn_01x03_Male") (at 170.18 91.44 0) (mirror y) (unit 1) + (in_bom yes) (on_board yes) + (uuid 75cabc2d-b4ca-40a6-b213-1426b43acf6d) + (property "Reference" "J2" (id 0) (at 168.91 86.36 0)) + (property "Value" "Output" (id 1) (at 168.91 96.52 0)) + (property "Footprint" "" (id 2) (at 170.18 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 170.18 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 34f45296-9d4b-447c-a137-a0c7f5e9a715)) + (pin "2" (uuid 24931d72-c08d-4036-ac99-e34e202b5506)) + (pin "3" (uuid 0124c0b9-efbc-4609-8591-314e60d29c4b)) + ) + + (symbol (lib_id "power:GND") (at 110.49 96.52 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid bcfa2161-99b3-4e19-a333-cbbbe9d84e7d) + (property "Reference" "#PWR?" (id 0) (at 110.49 102.87 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 110.49 101.6 0)) + (property "Footprint" "" (id 2) (at 110.49 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 110.49 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 7380b8a5-b1fe-45f0-8379-2b0020947544)) + ) + + (symbol (lib_id "Connector:Conn_01x03_Male") (at 102.87 91.44 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid beccd717-8d3e-486c-ba78-03c57132aa85) + (property "Reference" "J1" (id 0) (at 104.14 86.36 0)) + (property "Value" "Input" (id 1) (at 104.14 96.52 0)) + (property "Footprint" "" (id 2) (at 102.87 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 102.87 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid bfe1e533-09fa-4581-8f6b-115621188acd)) + (pin "2" (uuid 53dfc1b8-1106-438f-bfb4-0bfcfd8d229f)) + (pin "3" (uuid 8485226b-5766-48cd-ad8b-8aab301eda39)) + ) + + (sheet (at 124.46 99.06) (size 24.13 7.62) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid e8c4a65e-6309-437b-9b0b-4832fc4da973) + (property "Sheet name" "Low Pass Filter B" (id 0) (at 124.46 98.3484 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "filter.kicad_sch" (id 1) (at 124.46 107.2646 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + (pin "IN" input (at 124.46 102.87 180) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 8473dea1-aae1-487c-91fc-d3901ecccf5b) + ) + (pin "OUT" output (at 148.59 102.87 0) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 75bd8588-3a91-4377-a105-09500cf2ab50) + ) + ) + + (sheet (at 124.46 85.09) (size 24.13 7.62) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid f99568d4-601e-4f51-9998-989c9d6f69b3) + (property "Sheet name" "Low Pass Filter A" (id 0) (at 124.46 84.3784 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "filter.kicad_sch" (id 1) (at 124.46 93.2946 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + (pin "IN" input (at 124.46 88.9 180) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 84b992d3-8fef-4b8d-8e8e-b9dd3eeda6a2) + ) + (pin "OUT" output (at 148.59 88.9 0) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid fad95148-224a-4965-800b-1b9e78f5a4fc) + ) + ) + + (sheet_instances + (path "/" (page "1")) + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3" (page "2")) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973" (page "3")) + ) + + (symbol_instances + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/431ea6a1-54ca-474a-94e5-019b2198369c" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/bcfa2161-99b3-4e19-a333-cbbbe9d84e7d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C1") (unit 1) (value "150p") (footprint "") + ) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C2") (unit 1) (value "150p") (footprint "") + ) + (path "/beccd717-8d3e-486c-ba78-03c57132aa85" + (reference "J1") (unit 1) (value "Input") (footprint "") + ) + (path "/75cabc2d-b4ca-40a6-b213-1426b43acf6d" + (reference "J2") (unit 1) (value "Output") (footprint "") + ) + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R1") (unit 1) (value "100k") (footprint "") + ) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R2") (unit 1) (value "100k") (footprint "") + ) + ) +) diff --git a/tests/board_samples/kicad_6/shared_page_value_change_complex/filter.kicad_sch b/tests/board_samples/kicad_6/shared_page_value_change_complex/filter.kicad_sch new file mode 100644 index 00000000..37778835 --- /dev/null +++ b/tests/board_samples/kicad_6/shared_page_value_change_complex/filter.kicad_sch @@ -0,0 +1,223 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid b1187436-c896-448a-926e-98e9b75df996) + + (paper "A4") + + (lib_symbols + (symbol "Device:C" (pin_numbers hide) (pin_names (offset 0.254)) (in_bom yes) (on_board yes) + (property "Reference" "C" (id 0) (at 0.635 2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "C" (id 1) (at 0.635 -2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (id 2) (at 0.9652 -3.81 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "cap capacitor" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Unpolarized capacitor" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "C_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "C_0_1" + (polyline + (pts + (xy -2.032 -0.762) + (xy 2.032 -0.762) + ) + (stroke (width 0.508) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy -2.032 0.762) + (xy 2.032 0.762) + ) + (stroke (width 0.508) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "C_1_1" + (pin passive line (at 0 3.81 270) (length 2.794) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -3.81 90) (length 2.794) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "R" (id 0) (at 2.032 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "R" (id 1) (at 0 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at -1.778 0 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "R res resistor" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Resistor" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "R_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "R_0_1" + (rectangle (start -1.016 -2.54) (end 1.016 2.54) + (stroke (width 0.254) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "R_1_1" + (pin passive line (at 0 3.81 270) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -3.81 90) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "power:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "#PWR" (id 0) (at 0 -6.35 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 0 -3.81 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "global power" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Power symbol creates a global label with name \"GND\" , ground" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "GND_0_1" + (polyline + (pts + (xy 0 0) + (xy 0 -1.27) + (xy 1.27 -1.27) + (xy 0 -2.54) + (xy -1.27 -1.27) + (xy 0 -1.27) + ) + (stroke (width 0) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "GND_1_1" + (pin power_in line (at 0 0 270) (length 0) hide + (name "GND" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + ) + ) + ) + + (junction (at 115.57 63.5) (diameter 0) (color 0 0 0 0) + (uuid f0903ccd-ddaa-4fd7-a697-981f2d0f9397) + ) + + (wire (pts (xy 115.57 63.5) (xy 115.57 68.58)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 2d4790c8-46d7-4a9f-937f-bf3b2d8efada) + ) + (wire (pts (xy 88.9 63.5) (xy 96.52 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 39aed1ce-6762-43f2-82fa-7c9cbbad1bbd) + ) + (wire (pts (xy 115.57 76.2) (xy 115.57 82.55)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 3bc07038-b2b5-45e0-8cd1-21ab40e6b75f) + ) + (wire (pts (xy 115.57 63.5) (xy 127 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 5ed7720b-4ec3-4927-aa9a-3201ed3eca32) + ) + (wire (pts (xy 104.14 63.5) (xy 115.57 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 6660fa40-6f3f-4ef8-8139-af510388e89f) + ) + + (hierarchical_label "OUT" (shape output) (at 127 63.5 0) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 38c07dda-cb98-4962-b63e-de8104ed14d0) + ) + (hierarchical_label "IN" (shape input) (at 88.9 63.5 180) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid fef124b4-a5f0-4dd5-80b1-3800774fbd73) + ) + + (symbol (lib_id "power:GND") (at 115.57 82.55 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 2008b722-6f66-498d-8afb-79e172fe202d) + (property "Reference" "#PWR?" (id 0) (at 115.57 88.9 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 115.57 87.63 0)) + (property "Footprint" "" (id 2) (at 115.57 82.55 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 115.57 82.55 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 428fe857-2241-4f1f-b4de-cfb744d6d47c)) + ) + + (symbol (lib_id "Device:C") (at 115.57 72.39 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 3316c32a-0fe0-447f-ad05-e8a774318855) + (property "Reference" "C1" (id 0) (at 119.38 71.1199 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "150p" (id 1) (at 119.38 73.6599 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (id 2) (at 116.5352 76.2 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 115.57 72.39 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 2a7f634a-eeee-4d03-a085-23c5053ac8fc)) + (pin "2" (uuid 17af8374-6edb-4cba-b417-78ee4ed8db8e)) + ) + + (symbol (lib_id "Device:R") (at 100.33 63.5 90) (unit 1) + (in_bom yes) (on_board yes) + (uuid 6e279b82-cec2-44a1-9e20-451a25fb9868) + (property "Reference" "R1" (id 0) (at 100.33 58.42 90)) + (property "Value" "100k" (id 1) (at 100.33 60.96 90)) + (property "Footprint" "" (id 2) (at 100.33 65.278 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 100.33 63.5 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid b11eb219-0980-4284-98f4-0c978028fc3f)) + (pin "2" (uuid dcb1e8c5-0fc5-4595-83da-d83fbe9a9876)) + ) +) diff --git a/tests/board_samples/kicad_6/shared_page_value_change_complex/group.kicad_sch b/tests/board_samples/kicad_6/shared_page_value_change_complex/group.kicad_sch new file mode 100644 index 00000000..c20ed95c --- /dev/null +++ b/tests/board_samples/kicad_6/shared_page_value_change_complex/group.kicad_sch @@ -0,0 +1,50 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid ae7590fe-62f7-489d-9e1a-af74b73a2b78) + + (paper "A4") + + (lib_symbols + ) + + + (sheet (at 127 80.01) (size 24.13 7.62) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid 1a520d7d-3ba5-4c74-a100-97625e355b42) + (property "Sheet name" "Low Pass Filter A1" (id 0) (at 127 79.2984 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "filter.kicad_sch" (id 1) (at 127 88.2146 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + (pin "IN" input (at 127 83.82 180) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid ddc93f51-ee50-4796-b46c-e1583ce07223) + ) + (pin "OUT" output (at 151.13 83.82 0) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 7a02ef50-ccf3-4d78-abef-831054f8dbdf) + ) + ) + + (sheet (at 127 93.98) (size 24.13 7.62) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid ceaaef34-04ea-407a-8f1a-90d1b353a084) + (property "Sheet name" "Low Pass Filter B1" (id 0) (at 127 93.2684 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "filter.kicad_sch" (id 1) (at 127 102.1846 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + (pin "IN" input (at 127 97.79 180) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 4f917a76-f7cb-487e-936e-1d52f4db60d5) + ) + (pin "OUT" output (at 151.13 97.79 0) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid a3235e0d-ce4e-481b-a10d-8cd5307d4186) + ) + ) +) diff --git a/tests/board_samples/kicad_6/shared_page_value_change_complex/value_change.kicad_sch b/tests/board_samples/kicad_6/shared_page_value_change_complex/value_change.kicad_sch new file mode 100644 index 00000000..6a06ffa3 --- /dev/null +++ b/tests/board_samples/kicad_6/shared_page_value_change_complex/value_change.kicad_sch @@ -0,0 +1,387 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid 2edf3773-c8c4-44a8-b0bd-a7fa9d597fb5) + + (paper "A4") + + (lib_symbols + (symbol "Connector:Conn_01x03_Male" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes) + (property "Reference" "J" (id 0) (at 0 5.08 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "Conn_01x03_Male" (id 1) (at 0 -5.08 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "connector" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "Conn_01x03_Male_1_1" + (polyline + (pts + (xy 1.27 -2.54) + (xy 0.8636 -2.54) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 0) + (xy 0.8636 0) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 2.54) + (xy 0.8636 2.54) + ) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (rectangle (start 0.8636 -2.413) (end 0 -2.667) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 0.127) (end 0 -0.127) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (rectangle (start 0.8636 2.667) (end 0 2.413) + (stroke (width 0.1524) (type default) (color 0 0 0 0)) + (fill (type outline)) + ) + (pin passive line (at 5.08 2.54 180) (length 3.81) + (name "Pin_1" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 0 180) (length 3.81) + (name "Pin_2" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 5.08 -2.54 180) (length 3.81) + (name "Pin_3" (effects (font (size 1.27 1.27)))) + (number "3" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "power:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "#PWR" (id 0) (at 0 -6.35 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 0 -3.81 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "global power" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Power symbol creates a global label with name \"GND\" , ground" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "GND_0_1" + (polyline + (pts + (xy 0 0) + (xy 0 -1.27) + (xy 1.27 -1.27) + (xy 0 -2.54) + (xy -1.27 -1.27) + (xy 0 -1.27) + ) + (stroke (width 0) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "GND_1_1" + (pin power_in line (at 0 0 270) (length 0) hide + (name "GND" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + ) + ) + ) + + + (wire (pts (xy 148.59 102.87) (xy 153.67 102.87)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 014f4a41-f96a-440f-a7df-bff9cc8b584f) + ) + (wire (pts (xy 153.67 102.87) (xy 153.67 91.44)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 318d1a1c-c645-4371-9840-4addf9815390) + ) + (wire (pts (xy 119.38 91.44) (xy 119.38 102.87)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 4cf82e5c-3b1e-4592-86e1-831746fe0a50) + ) + (wire (pts (xy 148.59 88.9) (xy 165.1 88.9)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 6b782584-bbda-4063-871c-baa87b2e3a3a) + ) + (wire (pts (xy 119.38 102.87) (xy 124.46 102.87)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 9344469f-8a37-4d7b-b4fd-e1dff551e5c5) + ) + (wire (pts (xy 107.95 91.44) (xy 119.38 91.44)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 985d532a-ca7f-4177-9f5a-723e7cc92a38) + ) + (wire (pts (xy 162.56 93.98) (xy 162.56 96.52)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 9a66c46b-3815-4a1c-9c95-54dda20ca51a) + ) + (wire (pts (xy 110.49 93.98) (xy 110.49 96.52)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 9efc67a5-596f-4b7b-b65d-d36188443244) + ) + (wire (pts (xy 107.95 93.98) (xy 110.49 93.98)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid a16cd396-ad8f-4027-9a33-6323720f1d9e) + ) + (wire (pts (xy 165.1 93.98) (xy 162.56 93.98)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid b7ed1d31-2d13-4472-92b9-c2b0cfd3e355) + ) + (wire (pts (xy 153.67 91.44) (xy 165.1 91.44)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid ce8e6896-c0d6-441f-8ddd-cb3f340d1723) + ) + (wire (pts (xy 107.95 88.9) (xy 124.46 88.9)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid e82f25fe-3e57-41fb-8fba-6cb01942af70) + ) + + (text "Test for sheet reuse. Not a real life circuit.\nThis is a more complex case of \"shared_page_value_change\"\nWe'll change C2 and C4 from 150 pF to 220 pF\nAnd also C5 from 150 pF to 330 pF" + (at 13.97 38.1 0) + (effects (font (size 3.8 3.8)) (justify left bottom)) + (uuid 05df6345-718c-4e3b-b675-d4c4d21bec79) + ) + + (symbol (lib_id "power:GND") (at 162.56 96.52 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 431ea6a1-54ca-474a-94e5-019b2198369c) + (property "Reference" "#PWR?" (id 0) (at 162.56 102.87 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 162.56 101.6 0)) + (property "Footprint" "" (id 2) (at 162.56 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 162.56 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 76034050-bfce-465a-b3ca-155ba43fbbb0)) + ) + + (symbol (lib_id "Connector:Conn_01x03_Male") (at 170.18 91.44 0) (mirror y) (unit 1) + (in_bom yes) (on_board yes) + (uuid 75cabc2d-b4ca-40a6-b213-1426b43acf6d) + (property "Reference" "J2" (id 0) (at 168.91 86.36 0)) + (property "Value" "Output" (id 1) (at 168.91 96.52 0)) + (property "Footprint" "" (id 2) (at 170.18 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 170.18 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 34f45296-9d4b-447c-a137-a0c7f5e9a715)) + (pin "2" (uuid 24931d72-c08d-4036-ac99-e34e202b5506)) + (pin "3" (uuid 0124c0b9-efbc-4609-8591-314e60d29c4b)) + ) + + (symbol (lib_id "power:GND") (at 110.49 96.52 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid bcfa2161-99b3-4e19-a333-cbbbe9d84e7d) + (property "Reference" "#PWR?" (id 0) (at 110.49 102.87 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "GND" (id 1) (at 110.49 101.6 0)) + (property "Footprint" "" (id 2) (at 110.49 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "" (id 3) (at 110.49 96.52 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 7380b8a5-b1fe-45f0-8379-2b0020947544)) + ) + + (symbol (lib_id "Connector:Conn_01x03_Male") (at 102.87 91.44 0) (unit 1) + (in_bom yes) (on_board yes) + (uuid beccd717-8d3e-486c-ba78-03c57132aa85) + (property "Reference" "J1" (id 0) (at 104.14 86.36 0)) + (property "Value" "Input" (id 1) (at 104.14 96.52 0)) + (property "Footprint" "" (id 2) (at 102.87 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 102.87 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid bfe1e533-09fa-4581-8f6b-115621188acd)) + (pin "2" (uuid 53dfc1b8-1106-438f-bfb4-0bfcfd8d229f)) + (pin "3" (uuid 8485226b-5766-48cd-ad8b-8aab301eda39)) + ) + + (sheet (at 203.2 90.17) (size 25.4 13.97) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid 823c065d-99b5-46bc-b58e-234b048a4ddc) + (property "Sheet name" "Group 2" (id 0) (at 203.2 89.4584 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "group.kicad_sch" (id 1) (at 203.2 104.7246 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + ) + + (sheet (at 203.2 63.5) (size 25.4 13.97) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid a512402b-63f1-4de6-aa32-8bd40d7241ab) + (property "Sheet name" "Group 1" (id 0) (at 203.2 62.7884 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "group.kicad_sch" (id 1) (at 203.2 78.0546 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + ) + + (sheet (at 124.46 99.06) (size 24.13 7.62) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid e8c4a65e-6309-437b-9b0b-4832fc4da973) + (property "Sheet name" "Low Pass Filter B" (id 0) (at 124.46 98.3484 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "filter.kicad_sch" (id 1) (at 124.46 107.2646 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + (pin "IN" input (at 124.46 102.87 180) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 8473dea1-aae1-487c-91fc-d3901ecccf5b) + ) + (pin "OUT" output (at 148.59 102.87 0) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 75bd8588-3a91-4377-a105-09500cf2ab50) + ) + ) + + (sheet (at 124.46 85.09) (size 24.13 7.62) (fields_autoplaced) + (stroke (width 0.1524) (type solid) (color 0 0 0 0)) + (fill (color 0 0 0 0.0000)) + (uuid f99568d4-601e-4f51-9998-989c9d6f69b3) + (property "Sheet name" "Low Pass Filter A" (id 0) (at 124.46 84.3784 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + ) + (property "Sheet file" "filter.kicad_sch" (id 1) (at 124.46 93.2946 0) + (effects (font (size 1.27 1.27)) (justify left top)) + ) + (pin "IN" input (at 124.46 88.9 180) + (effects (font (size 1.27 1.27)) (justify left)) + (uuid 84b992d3-8fef-4b8d-8e8e-b9dd3eeda6a2) + ) + (pin "OUT" output (at 148.59 88.9 0) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid fad95148-224a-4965-800b-1b9e78f5a4fc) + ) + ) + + (sheet_instances + (path "/" (page "1")) + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3" (page "2")) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973" (page "3")) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab" (page "4")) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc" (page "5")) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/1a520d7d-3ba5-4c74-a100-97625e355b42" (page "6")) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/ceaaef34-04ea-407a-8f1a-90d1b353a084" (page "7")) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/1a520d7d-3ba5-4c74-a100-97625e355b42" (page "8")) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/ceaaef34-04ea-407a-8f1a-90d1b353a084" (page "9")) + ) + + (symbol_instances + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/ceaaef34-04ea-407a-8f1a-90d1b353a084/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/1a520d7d-3ba5-4c74-a100-97625e355b42/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/1a520d7d-3ba5-4c74-a100-97625e355b42/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/ceaaef34-04ea-407a-8f1a-90d1b353a084/2008b722-6f66-498d-8afb-79e172fe202d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/431ea6a1-54ca-474a-94e5-019b2198369c" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/bcfa2161-99b3-4e19-a333-cbbbe9d84e7d" + (reference "#PWR?") (unit 1) (value "GND") (footprint "") + ) + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C1") (unit 1) (value "150p") (footprint "") + ) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C2") (unit 1) (value "150p") (footprint "") + ) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/ceaaef34-04ea-407a-8f1a-90d1b353a084/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C3") (unit 1) (value "150p") (footprint "") + ) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/1a520d7d-3ba5-4c74-a100-97625e355b42/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C4") (unit 1) (value "150p") (footprint "") + ) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/ceaaef34-04ea-407a-8f1a-90d1b353a084/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C5") (unit 1) (value "150p") (footprint "") + ) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/1a520d7d-3ba5-4c74-a100-97625e355b42/3316c32a-0fe0-447f-ad05-e8a774318855" + (reference "C6") (unit 1) (value "150p") (footprint "") + ) + (path "/beccd717-8d3e-486c-ba78-03c57132aa85" + (reference "J1") (unit 1) (value "Input") (footprint "") + ) + (path "/75cabc2d-b4ca-40a6-b213-1426b43acf6d" + (reference "J2") (unit 1) (value "Output") (footprint "") + ) + (path "/f99568d4-601e-4f51-9998-989c9d6f69b3/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R1") (unit 1) (value "100k") (footprint "") + ) + (path "/e8c4a65e-6309-437b-9b0b-4832fc4da973/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R2") (unit 1) (value "100k") (footprint "") + ) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/ceaaef34-04ea-407a-8f1a-90d1b353a084/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R3") (unit 1) (value "100k") (footprint "") + ) + (path "/a512402b-63f1-4de6-aa32-8bd40d7241ab/1a520d7d-3ba5-4c74-a100-97625e355b42/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R4") (unit 1) (value "100k") (footprint "") + ) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/ceaaef34-04ea-407a-8f1a-90d1b353a084/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R5") (unit 1) (value "100k") (footprint "") + ) + (path "/823c065d-99b5-46bc-b58e-234b048a4ddc/1a520d7d-3ba5-4c74-a100-97625e355b42/6e279b82-cec2-44a1-9e20-451a25fb9868" + (reference "R6") (unit 1) (value "100k") (footprint "") + ) + ) +) diff --git a/tests/test_plot/test_int_bom.py b/tests/test_plot/test_int_bom.py index b304f3f8..f563e854 100644 --- a/tests/test_plot/test_int_bom.py +++ b/tests/test_plot/test_int_bom.py @@ -1757,24 +1757,31 @@ def test_int_bom_subparts_3(test_dir): ctx.clean_up() -@pytest.mark.skipif(not context.ki7(), reason="Target is v7") +@pytest.mark.skipif(not context.ki6(), reason="Target is v6+") def test_value_change_1(test_dir): prj = 'value_change' - ctx = context.TestContextSCH(test_dir, 'shared_page_value_change/'+prj, 'value_change_1', 'BoM') + ctx = context.TestContextSCH(test_dir, 'shared_page_value_change/'+prj, 'value_change_1', 'Modified') ctx.run() - rows, header, info = ctx.load_csv(prj+'-bom_different_filters.csv') + sch = ctx.expect_out_file_d(prj+'.kicad_sch') + ctx = context.TestContextSCH(test_dir, 'shared_page_value_change_complex/'+prj, 'int_bom_csv_no_info', 'BoM') + ctx.run(no_board_file=True, extra=['-e', sch]) + rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, ['C1', 'C2', 'J1', 'J2', 'R1', 'R2'], vals={'C1': '150p', 'C2': '220p'}, val_column=header.index('Value')) ctx.clean_up() -@pytest.mark.skipif(not context.ki7(), reason="Target is v7") +@pytest.mark.skipif(not context.ki6(), reason="Target is v6+") def test_value_change_2(test_dir): prj = 'value_change' - ctx = context.TestContextSCH(test_dir, 'shared_page_value_change_complex/'+prj, 'value_change_2', 'BoM') + ctx = context.TestContextSCH(test_dir, 'shared_page_value_change_complex/'+prj, 'value_change_2', 'Modified') ctx.run() - rows, header, info = ctx.load_csv(prj+'-bom_different_filters.csv') + sch = ctx.expect_out_file_d(prj+'.kicad_sch') + # assert False + ctx = context.TestContextSCH(test_dir, 'shared_page_value_change_complex/'+prj, 'int_bom_csv_no_info', 'BoM') + ctx.run(no_board_file=True, extra=['-e', sch]) + rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 5, None, ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'J1', 'J2', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6'], diff --git a/tests/yaml_samples/value_change_1.kibot.yaml b/tests/yaml_samples/value_change_1.kibot.yaml index e611dd76..fa070732 100644 --- a/tests/yaml_samples/value_change_1.kibot.yaml +++ b/tests/yaml_samples/value_change_1.kibot.yaml @@ -34,11 +34,3 @@ outputs: dir: Modified options: copy_project: true - - - name: bom_internal - comment: "Bill of Materials in CSV format" - type: bom - dir: BoM - options: - csv: - hide_stats_info: true diff --git a/tests/yaml_samples/value_change_2.kibot.yaml b/tests/yaml_samples/value_change_2.kibot.yaml index 4578a5e4..286eff02 100644 --- a/tests/yaml_samples/value_change_2.kibot.yaml +++ b/tests/yaml_samples/value_change_2.kibot.yaml @@ -48,11 +48,3 @@ outputs: dir: Modified options: copy_project: true - - - name: bom_internal - comment: "Bill of Materials in CSV format" - type: bom - dir: BoM - options: - csv: - hide_stats_info: true