From 661332c3ce7562b30545ae1773d30a784bcbc0db Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 29 Jul 2018 23:22:26 +0200 Subject: o Support for resolving 'mpn' fields from digikey. Creates 'digikey-part-stub', can be used to download the entire part later on. --- src/ee/digikey/doit.py | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/ee/digikey/doit.py (limited to 'src/ee/digikey/doit.py') diff --git a/src/ee/digikey/doit.py b/src/ee/digikey/doit.py new file mode 100644 index 0000000..74259bb --- /dev/null +++ b/src/ee/digikey/doit.py @@ -0,0 +1,87 @@ +import logging + +import ee.digikey as dk +from ee.doit import DoItConfig +from ee.ds import DataSet + +logger = logging.getLogger(__name__) + +doit_config = DoItConfig() + + +def resolve_schematic_components(output: DataSet, in_ds: DataSet): + def find(field, value): + return [o for o in output.items() if o.object_type.name == "digikey-part-stub" and o.get(field) == value] + + def save(p: dk.DigikeyProduct): + logger.info("Found part, dpn={}, mpn={}".format(p.part_number, p.mpn)) + + return output.create_object("digikey-part-stub", p.part_number, replace=True). \ + set("part-number", p.part_number). \ + set("mpn", p.mpn). \ + set("description", p.description). \ + set("quantity-available", p.quantity_available). \ + set("url", p.url) + + digikey = dk.Digikey() + client = dk.DigikeyClient(digikey, on_download=logger.info) + + components = [o for o in in_ds.items() if o.object_type.name == "component"] + + for mpn in sorted({c.get("mpn") for c in components if c.get("mpn")}): + # TODO: support searching by value and digikey part number directly. Priority should be "digikey", "mpn" and + # "value", first field present should be used. + + dk_components = find("mpn", mpn) + + if len(dk_components): + logger.info("Already resolved {} to {}".format(mpn, ", ".join([c.get("mpn") for c in dk_components]))) + continue + + logger.info("Looking up {}".format(mpn)) + response = client.search(mpn) + + if response.response_type == dk.SearchResponseTypes.SINGLE: + save(response.products[0]) + elif response.response_type == dk.SearchResponseTypes.MANY: + # A search for "FOO" might return products "FOO" and "FOOZ" so we pick out the ones with the matching mpn + # This will often be more than one product, but digikey shows the same part in different packagings. + viable_products = [p for p in response.products if p.mpn == mpn] + + if len(viable_products) == 0: + logger.warning("BUG: Got multiple hits ({}) but didn't find anyone that matched the MPN. Strange!". + format(len(response.products))) + else: + if len(viable_products) == 1: + part = viable_products[0] + else: + # Pick the first one, should be as good as any + part = sorted(viable_products, key=lambda x: x.part_number)[0] + + logger.info("Got multiple hits ({})".format(len(viable_products))) + + save(part) + elif response.response_type == dk.SearchResponseTypes.TOO_MANY: + logger.warning("to many matches") + elif response.response_type == dk.SearchResponseTypes.NO_MATCHES: + logger.warning("no matches") + + +def task_digikey_resolve_schematic_components(): + out_data_set, in_data_sets = doit_config.data_sets_for(task_digikey_resolve_schematic_components) + + def action(): + in_ds = doit_config.dsm.load_data_sets(in_data_sets) + + with doit_config.dsm.create_rw(out_data_set, clean=False) as output: + resolve_schematic_components(output, in_ds) + + return dict( + file_dep=[doit_config.dsm.cookie_for_ds(ds) for ds in in_data_sets], + actions=[action], + targets=[doit_config.dsm.cookie_for_ds(out_data_set)], + ) + + +doit_config.set_data_sets_for(task_digikey_resolve_schematic_components, + "digikey-resolved-parts", "components") -- cgit v1.2.3