-
Notifications
You must be signed in to change notification settings - Fork 494
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for Eagle / Fusion 360 Electronics (#216)
* initial commit - added EagleParser This adds a third parser for JSON files produced from Eagle or Fusion 360 Electronics using the ULP available at https://github.com/Funkenjaeger/brd2json * Stylistic fixes * Refactored EagleParser to GenericJsonParser, added 'spec version' logic and more robust error handling * _type and _spec_version in top level object only * #216 code review updates * Fix format string syntax * Initial implementation of JSON validation with schema in GenericJsonParser * Updated to implement the rest of the pcbdata struct as defined in DATAFORMAT.md * Fix ExtraData (array vs. object) * Initial cut at support for extra_fields in generic JSON schema & parser * More schema updates based on code review * Removed parser-specific code from the core code in ibom.py Pushed all parsing of extra_fields data down into the respective parsers. This includes some experimental code associated with GenericJsonParser, as well as the existing netlist-based (kicad-specific) code that was in ibom.py * #216 code review updates * Revert to returning extra_fields only within components * Extra field data embedded in components for kicad parser also * Override board bounding box from generic JSON based on edges * Restore warning for outdated netlist/xml in kicad parser * Fix clerical issues noted in code review * Fix improper access of footprint ref in kicad.py
- Loading branch information
1 parent
d75e74f
commit 6350be3
Showing
7 changed files
with
777 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import io | ||
import json | ||
from jsonschema import validate, ValidationError | ||
|
||
from .common import EcadParser, Component, BoundingBox | ||
|
||
|
||
class GenericJsonParser(EcadParser): | ||
COMPATIBLE_SPEC_VERSIONS = [1] | ||
|
||
def get_generic_json_pcb(self): | ||
from os import path | ||
with io.open(self.file_name, 'r') as f: | ||
pcb = json.load(f) | ||
|
||
if 'spec_version' not in pcb: | ||
raise ValidationError("'spec_version' is a required property") | ||
|
||
if pcb['spec_version'] not in self.COMPATIBLE_SPEC_VERSIONS: | ||
raise ValidationError("Unsupported spec_version ({})" | ||
.format(pcb['spec_version'])) | ||
|
||
schema_dir = path.join(path.dirname(__file__), 'schema') | ||
schema_file_name = path.join(schema_dir, | ||
'genericjsonpcbdata_v{}.schema' | ||
.format(pcb['spec_version'])) | ||
|
||
with io.open(schema_file_name, 'r') as f: | ||
schema = json.load(f) | ||
|
||
validate(instance=pcb, schema=schema) | ||
|
||
return pcb | ||
|
||
def _verify(self, pcb): | ||
|
||
"""Spot check the pcb object.""" | ||
|
||
if len(pcb['pcbdata']['footprints']) != len(pcb['components']): | ||
self.logger.error("Length of components list doesn't match" | ||
" length of footprints list.") | ||
return False | ||
|
||
return True | ||
|
||
def parse(self): | ||
try: | ||
pcb = self.get_generic_json_pcb() | ||
except ValidationError as e: | ||
self.logger.error('File {f} does not comply with json schema. {m}' | ||
.format(f=self.file_name, m=e.message)) | ||
return None, None | ||
|
||
if not self._verify(pcb): | ||
self.logger.error('File {} does not appear to be valid generic' | ||
' InteractiveHtmlBom json file.' | ||
.format(self.file_name)) | ||
return None, None | ||
|
||
self.logger.info('Successfully parsed {}'.format(self.file_name)) | ||
|
||
pcbdata = pcb['pcbdata'] | ||
components = [Component(**c) for c in pcb['components']] | ||
|
||
# override board bounding box based on edges | ||
board_outline_bbox = BoundingBox() | ||
for drawing in pcbdata['edges']: | ||
self.add_drawing_bounding_box(drawing, board_outline_bbox) | ||
if board_outline_bbox.initialized(): | ||
pcbdata['edges_bbox'] = board_outline_bbox.to_dict() | ||
|
||
if self.config.extra_fields: | ||
for c in components: | ||
extra_field_data = {} | ||
for f in self.config.extra_fields: | ||
fv = ("" if f not in c.extra_fields else c.extra_fields[f]) | ||
extra_field_data[f] = fv | ||
c.extra_fields = extra_field_data | ||
|
||
return pcbdata, components |
Oops, something went wrong.