aboutsummaryrefslogtreecommitdiff
path: root/src/ee/digikey/functions.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ee/digikey/functions.py')
-rw-r--r--src/ee/digikey/functions.py157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/ee/digikey/functions.py b/src/ee/digikey/functions.py
new file mode 100644
index 0000000..047fad1
--- /dev/null
+++ b/src/ee/digikey/functions.py
@@ -0,0 +1,157 @@
+import re
+from typing import List, Tuple, Union, Mapping, Callable, Any
+
+from ee import EeVal, EeException
+from ee.part import Part
+from ee.xml import types, uris
+
+__all__ = ["normalize_facts"]
+
+
+# TODO: this should be moved to a generic normalizer
+def handle_tolerance(tolerance: types.Fact, capacitance: types.Fact) -> List[types.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 [types.Fact(key=uris.make_fact_key(key), label=label, value=str(value)) for key, label, value in facts]
+
+
+def re_parser(pattern, kis: List[Tuple[str, int]]):
+ r = re.compile(pattern)
+
+ def parse(value):
+ m = r.match(value)
+
+ if not m:
+ return
+
+ return [(k, m.group(i)) for k, i in kis]
+
+ return parse
+
+
+def no_parser(key):
+ def parse(value):
+ return key, value
+
+ return parse
+
+
+def ee_val_parser(key):
+ def parse(value):
+ return key, EeVal.parse(value)
+
+ return parse
+
+
+_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)
+_parsers: Mapping[int, Callable[[str], Any]] = {
+ 3: no_parser("tolerance"),
+ 1471: ee_val_parser("voltage-input-min"), # Voltage - Input (Min)
+ 573: ee_val_parser("voltage-input-max"), # Voltage - Input (Max)
+ 1429: ee_val_parser("voltage-output-max"), # Voltage - Output (Max)
+ 252: re_parser(_operating_temperature_re, [("temperature-min", 1), ("temperature-max", 2)]),
+ 1686: re_parser(_operating_temperature_re, [("temperature-junction-min", 1), ("temperature-junction-max", 2)]),
+
+ 1500: re_parser(_height_seated_re, [("part-height", 2)]),
+ 884: re_parser(_land_size_re, [("land-size-x", 3), ("land-size-y", 4)]),
+
+ 2049: ee_val_parser("capacitance"),
+ 2079: ee_val_parser("voltage-rating"),
+}
+
+
+# noinspection PyUnusedLocal
+def normalize_facts(**kwargs):
+ parsers: Mapping[str, Callable[[str], Any]] = {uris.make_digikey_fact_key(k): v for k, v in _parsers.items()}
+
+ def on_part(part: Part) -> Part:
+ for dk_key, parser in parsers.items():
+ value = part.facts.get_value(dk_key)
+
+ if value is None or value == "-":
+ continue
+
+ res = parser(value)
+
+ if res is not None:
+ if isinstance(res, list):
+ for key, value in res:
+ key = uris.make_fact_key(key)
+ part.facts.add(key, value)
+ else:
+ key, value = res
+ key = uris.make_fact_key(key)
+ part.facts.add(key, value)
+
+ return part
+
+ return on_part
+
+
+def default(**kwargs):
+ function_factories = [
+ normalize_facts,
+ ]
+
+ functions = [factory(**kwargs) for factory in function_factories]
+ functions = [f for f in functions if f is not None]
+
+ def on_part(part: Part) -> Part:
+ for f in functions:
+ part = f(part)
+
+ return part
+
+ return on_part