import re from pathlib import Path from typing import List, Tuple, Union from ee import EeVal, EeException from ee.part import PartDb, load_db, save_db from ee.xml import bomFile, uris __all__ = ["normalize_facts"] # TODO: this should be moved to a generic normalizer def handle_tolerance(tolerance: bomFile.Fact, capacitance: bomFile.Fact) -> List[bomFile.Fact]: cap_value = float(EeVal.parse(capacitance.valueProp)) s = tolerance.valueProp print("tolerance: {}".format(s)) is_plus_minus = s.startswith("±") s = s[1:] if is_plus_minus else s is_percent = s.endswith("%") is_farad = s.endswith("F") print("tolerance={}, is_plus_minus={}, is_farad={}, is_percent={}".format( tolerance.valueProp, is_plus_minus, is_farad, is_percent)) print("capacitance={}".format(EeVal.parse(capacitance.valueProp))) low_pct = low_value = None high_pct = high_value = None facts = [] # type: List[Tuple[str, str, Union[str, EeVal]]] if is_farad: s = s[0:-1] if is_farad else s try: farad = EeVal.parse(s) except EeException: farad = None elif is_percent: s = s[0:-1] pct_value = int(s) if is_plus_minus: low_pct = high_pct = str(pct_value) pct = float(pct_value) / 100 low_value = EeVal(value=cap_value * (1 - pct), exp=1, unit="F") high_value = EeVal(value=cap_value * (1 + pct), exp=1, unit="F") else: raise EeException("bad combination") if low_pct: facts.append(("tolerance-percent-lower", "Tolerance, lower (%)", low_pct)) if high_pct: facts.append(("tolerance-percent-upper", "Tolerance, upper (%)", high_pct)) if low_value: facts.append(("tolerance-lower", "Tolerance, lower", low_value)) if high_value: facts.append(("tolerance-upper", "Tolerance, upper", high_value)) if low_pct and low_pct == high_pct: facts.append(("tolerance-percent", "Tolerance (±%)", low_pct)) return [bomFile.Fact(key=uris.make_fact_key(key), label=label, value=str(value)) for key, label, value in facts] _operating_temperature_re = re.compile("-([0-9]+)°C ~ ([0-9])+°C") _height_seated_re = re.compile("([0-9]+\\.[0-9]+)\" \\(([0-9]+\\.[0-9]+)mm\\)") _land_size_re = re.compile("([0-9]+\\.[0-9]+)\" L x ([0-9]+\\.[0-9]+)\" W " "\\(([0-9]+\\.[0-9]+)mm x ([0-9]+\\.[0-9]+)mm\\)") # 0.260" L x 0.260" W (6.60mm x 6.60mm) def normalize_facts(in_dir: Path, out_dir: Path): print("in: {}, out: {}".format(in_dir, out_dir)) in_db = load_db(in_dir) out_parts = PartDb() for part in in_db.iterparts(): # type: bomFile.Part fact_list: bomFile.FactList = part.factsProp if fact_list is None: continue in_facts: List[bomFile.Fact] = fact_list.factProp out_facts = [] for f in in_facts: key = uris.parse_digikey_fact_key(f.keyProp) out_fact = None value = f.valueProp if value == "-": continue try: if key == 3: out_fact = bomFile.Fact(key=uris.make_fact_key("tolerance"), label="Tolerance", value=value) elif key == 252: m = _operating_temperature_re.match(value) if m: mn = m.group(1) mx = m.group(2) out_facts.extend([ bomFile.Fact(key=uris.make_fact_key("temperature-min"), label="Min temperature", value=mn), bomFile.Fact(key=uris.make_fact_key("temperature-max"), label="Max temperature", value=mx)]) elif key == 1500: m = _height_seated_re.match(value) if m: out_fact = bomFile.Fact(key=uris.make_fact_key("part-height"), label="Height", value=m.group(2)) else: print("{}: bad str: '{}'".format(key, value)) elif key == 884: m = _land_size_re.match(value) if m: out_facts.extend([ bomFile.Fact(key=uris.make_fact_key("land-size-x"), label="Land size, X", value=m.group(3)), bomFile.Fact(key=uris.make_fact_key("land-size-y"), label="Land size, Y", value=m.group(4))]) elif key == 2049: val = EeVal.parse(value) out_fact = bomFile.Fact(key=uris.make_fact_key("capacitance"), label="Capacitance", value=str(val)) elif key == 2079: val = EeVal.parse(value) out_fact = bomFile.Fact(key=uris.make_fact_key("voltage-rating"), label="Voltage rating", value=str(val)) else: pass # fact ignored except EeException: pass if out_fact: out_facts.append(out_fact) if len(out_facts) == 0: continue part.factsProp.factProp = out_facts out_parts.add_entry(part, True) print("Saving {} work parts".format(out_parts.size())) save_db(out_dir, out_parts)