aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ee/__init__.py121
-rw-r--r--src/ee/digikey/__init__.py8
-rw-r--r--src/ee/kicad/__init__.py7
-rw-r--r--src/ee/kicad/bom/__init__.py1
-rw-r--r--src/ee/kicad/bom_tool/__init__.py12
-rw-r--r--src/ee/kicad/model.py2
-rw-r--r--src/ee/kicad/to_bom.py3
-rw-r--r--src/ee/tools/__init__.py18
-rw-r--r--src/ee/tools/digikey_download_facts.py33
9 files changed, 116 insertions, 89 deletions
diff --git a/src/ee/__init__.py b/src/ee/__init__.py
index d3885c3..7fa2243 100644
--- a/src/ee/__init__.py
+++ b/src/ee/__init__.py
@@ -10,69 +10,72 @@ __all__ = [
"read_ltspice_raw"
]
+
class EeException(Exception):
pass
+
@total_ordering
class EeVal(object):
- from decimal import Decimal
- units = ['F', 'Ohm', '\u2126', 'H']
- exponents = {
- 'f': -15,
- 'p': -12,
- 'n': -9,
- 'u': -6,
- '\u00B5': -6, # The micro symbol
- 'm': -3,
-
- 'k': 3,
- 'M': 6,
- 'G': 9,
- 'T': 12,
- 'P': 15,
- 'E': 18,
- }
- r = re.compile("([0-9]+\\.[0-9]+|\\.?[0-9]+|[0-9]+\\.?) *([" + "".join(exponents.keys()) + "]?) *(" + "|".join(units) + "?)")
-
- def __init__(self, s):
- m = EeVal.r.match(s)
- if not m:
- raise EeException("Could not parse value: " + str(s))
- gs = m.groups()
- value = float(gs[0])
- exp = gs[1].strip()
- exp = EeVal.exponents.get(exp) if len(exp) > 0 else 0
- unit = gs[2]
- if value < 1:
- e = math.ceil(math.log10(value))
- exp = exp + e
- value = value * math.pow(10, -e)
- self._value = float(value)
- self._exp = exp
- self._unit = unit if len(unit) > 0 else None
-
- @property
- def value(self):
- return self.__float__()
-
- @property
- def unit(self):
- return self._unit
-
- def __hash__(self):
- return hash((self.__float__(), self._unit))
-
- def __eq__(self, other):
- return ((self.__float__(), self._unit) == (other.__float__(), other._unit))
-
- def __lt__(self, other):
- return ((self.__float__(), self._unit) < (other.__float__(), other._unit))
-
- def __str__(self):
- return eng_str(self.__float__(), self._unit)
-
- def __float__(self):
- return self._value * math.pow(10, self._exp)
+ from decimal import Decimal
+ units = ['F', 'Ohm', '\u2126', 'H']
+ exponents = {
+ 'f': -15,
+ 'p': -12,
+ 'n': -9,
+ 'u': -6,
+ '\u00B5': -6, # The micro symbol
+ 'm': -3,
+
+ 'k': 3,
+ 'M': 6,
+ 'G': 9,
+ 'T': 12,
+ 'P': 15,
+ 'E': 18,
+ }
+ r = re.compile(
+ "([0-9]+\\.[0-9]+|\\.?[0-9]+|[0-9]+\\.?) *([" + "".join(exponents.keys()) + "]?) *(" + "|".join(units) + "?)")
+
+ def __init__(self, s):
+ m = EeVal.r.match(s)
+ if not m:
+ raise EeException("Could not parse value: " + str(s))
+ gs = m.groups()
+ value = float(gs[0])
+ exp = gs[1].strip()
+ exp = EeVal.exponents.get(exp) if len(exp) > 0 else 0
+ unit = gs[2]
+ if value < 1:
+ e = math.ceil(math.log10(value))
+ exp = exp + e
+ value = value * math.pow(10, -e)
+ self._value = float(value)
+ self._exp = exp
+ self._unit = unit if len(unit) > 0 else None
+
+ @property
+ def value(self):
+ return self.__float__()
+
+ @property
+ def unit(self):
+ return self._unit
+
+ def __hash__(self):
+ return hash((self.__float__(), self._unit))
+
+ def __eq__(self, other):
+ return ((self.__float__(), self._unit) == (other.__float__(), other._unit))
+
+ def __lt__(self, other):
+ return ((self.__float__(), self._unit) < (other.__float__(), other._unit))
+
+ def __str__(self):
+ return eng_str(self.__float__(), self._unit)
+
+ def __float__(self):
+ return self._value * math.pow(10, self._exp)
class LtSpiceRaw(object):
@@ -187,7 +190,7 @@ class LtSpiceReader(object):
if line[-1] == '\n' or line[-1] == 0x0a:
line = line[:-1]
- # print("len(line)={}, line={}".format(len(line), str(line)))
+ # print("len(line)={}, line={}".format(len(line), str(line)))
line = line.decode(encoding="utf-16")
if self.mode == 'header':
diff --git a/src/ee/digikey/__init__.py b/src/ee/digikey/__init__.py
index 1315f96..23569f9 100644
--- a/src/ee/digikey/__init__.py
+++ b/src/ee/digikey/__init__.py
@@ -93,11 +93,13 @@ class DigikeyProduct(object):
def to_ini(self):
c = configparser.ConfigParser()
- c["overview"] = {}; overview = c["overview"]
+ c["overview"] = {};
+ overview = c["overview"]
overview["part_number"] = self.part_number
if self.mpn:
overview["mpn"] = self.mpn
- c["attributes"] = {}; attributes = c["attributes"]
+ c["attributes"] = {};
+ attributes = c["attributes"]
for a in self.attributes:
key = "{}/{}".format(a.attribute_type.id, a.attribute_type.label)
key = key.replace("%", "_")
@@ -112,7 +114,6 @@ class DigikeyProduct(object):
overview = c["overview"]
attributes = []
for k, value in c.items("attributes"):
-# print("k={}".format(k))
(type_id, label) = DigikeyProduct.from_ini_r.match(k).groups()
a_type = digikey.get_attribute_type(type_id, label)
attributes.append(DigikeyAttributeValue(value, a_type))
@@ -291,6 +292,7 @@ class DigikeyClient(object):
else:
return DigikeySearchResponse(1, SearchResponseTypes.NO_MATCHES)
+
class DigikeyRepository(object):
def __init__(self, digikey, path):
self._digikey = digikey
diff --git a/src/ee/kicad/__init__.py b/src/ee/kicad/__init__.py
index 5187a9c..d2d48da 100644
--- a/src/ee/kicad/__init__.py
+++ b/src/ee/kicad/__init__.py
@@ -29,6 +29,7 @@ def to_pandas(obj: Any, **kwarg):
def to_pandas_schematic(sch: Schematic):
# These fields will always be put first.
special_fields = ["ref", "ref_type", "ref_num", "value"]
+
def make_dict(c: Component):
fields = {
"ref": c.ref,
@@ -37,7 +38,7 @@ def to_pandas(obj: Any, **kwarg):
"value": c.value,
"footprint": c.footprint,
}
- fields.update({f.name:f.value for f in c.fields if f.is_custom})
+ fields.update({f.name: f.value for f in c.fields if f.is_custom})
return fields
components = sch.components
@@ -56,8 +57,8 @@ def to_pandas(obj: Any, **kwarg):
columns = set([key for row in data for key in list(row)]) - set(special_fields)
columns = special_fields + list(columns)
- return pandas.DataFrame(data=data, columns=columns).\
- set_index("ref").\
+ return pandas.DataFrame(data=data, columns=columns). \
+ set_index("ref"). \
sort_values(["ref_type", "ref_num"])
if isinstance(obj, Schematic):
diff --git a/src/ee/kicad/bom/__init__.py b/src/ee/kicad/bom/__init__.py
index a36068b..0392d66 100644
--- a/src/ee/kicad/bom/__init__.py
+++ b/src/ee/kicad/bom/__init__.py
@@ -97,7 +97,6 @@ class Bom(object):
for field in fields:
data[field].append(c[field] if field in c else None)
- # del data[ref_field_name]
data[ref_field_name] = refs
data[value_field_name] = values
return pandas.DataFrame(data=data, index=refs)
diff --git a/src/ee/kicad/bom_tool/__init__.py b/src/ee/kicad/bom_tool/__init__.py
index f5d2e4f..3e28eaf 100644
--- a/src/ee/kicad/bom_tool/__init__.py
+++ b/src/ee/kicad/bom_tool/__init__.py
@@ -103,12 +103,12 @@ def to_panda(bom, bom_settings, csv_format): # type: (Bom, BomSettings, CsvForm
# refs.append(functools.reduce(lambda a, b: a + ' ' + b, [c.ref for c in cs], ''))
print("group={}".format(gs))
- # return pd.DataFrame(data={
- # 'count': counts,
- # 'mpn': mpns,
- # 'dpn': dpns,
- # 'refs': refs,
- # })
+ # return pd.DataFrame(data={
+ # 'count': counts,
+ # 'mpn': mpns,
+ # 'dpn': dpns,
+ # 'refs': refs,
+ # })
else:
for ref, c in filtered:
for key, value in c:
diff --git a/src/ee/kicad/model.py b/src/ee/kicad/model.py
index a9b0c02..7d9a437 100644
--- a/src/ee/kicad/model.py
+++ b/src/ee/kicad/model.py
@@ -129,7 +129,7 @@ class Component(object):
def get_field(self, name) -> ComponentField:
for f in self.fields:
if name.lower() == f.name.lower():
- return f
+ return f
class Sheet(object):
diff --git a/src/ee/kicad/to_bom.py b/src/ee/kicad/to_bom.py
index 9a4f950..62eb075 100644
--- a/src/ee/kicad/to_bom.py
+++ b/src/ee/kicad/to_bom.py
@@ -1,3 +1,4 @@
+from typing import Iterable
from xml.etree.ElementTree import Element
from ee.kicad.model import *
@@ -34,7 +35,7 @@ def comp(c: Component) -> Element:
return comp
-def to_bom(schematic: Schematic) -> Component:
+def to_bom(schematic: Schematic) -> Iterable[Component]:
return [c for c in sorted(schematic.components) if c.ref_type != "#PWR" and c.ref_type != "#FLG"]
diff --git a/src/ee/tools/__init__.py b/src/ee/tools/__init__.py
index 893ee31..136bdf1 100644
--- a/src/ee/tools/__init__.py
+++ b/src/ee/tools/__init__.py
@@ -1,4 +1,5 @@
import os.path
+from colors import color
def _mkdir_and_open(path):
@@ -19,3 +20,20 @@ def mk_parents(path: str):
if not os.path.isdir(dirname):
os.mkdir(dirname)
+
+
+class Log(object):
+ def __init__(self):
+ pass
+
+ def warn(self, msg):
+ print(color(msg, "orange"))
+
+ def info(self, msg):
+ print(color(msg, "orange"))
+
+ def debug(self, msg):
+ print(color(msg, "orange"))
+
+
+log = Log()
diff --git a/src/ee/tools/digikey_download_facts.py b/src/ee/tools/digikey_download_facts.py
index 950623f..c947b67 100644
--- a/src/ee/tools/digikey_download_facts.py
+++ b/src/ee/tools/digikey_download_facts.py
@@ -2,11 +2,9 @@ import argparse
from itertools import *
from functools import total_ordering
-from colors import color
-
import ee.digikey as dk
from ee.digikey import SearchResponseTypes, DigikeyProduct
-from ee.tools import mk_parents
+from ee.tools import log
@total_ordering
@@ -24,6 +22,7 @@ class Query(object):
def __hash__(self):
return hash((self.is_mpn, self.query))
+
parser = argparse.ArgumentParser(description="Download facts about parts from Digi-Key")
parser.add_argument("--out",
@@ -47,7 +46,7 @@ parser.add_argument("--force",
args = parser.parse_args()
digikey = dk.Digikey()
-client = dk.DigikeyClient(digikey, on_download=lambda s: print(color(s, 'grey')))
+client = dk.DigikeyClient(digikey, on_download=log.debug)
repo = dk.DigikeyRepository(digikey, args.out)
@@ -62,6 +61,7 @@ if args.part:
if args.sch:
from ee.kicad import read_schematic, to_bom
+
sch = read_schematic(args.sch)
for c in to_bom(sch):
digikey = c.get_field("digikey")
@@ -75,43 +75,46 @@ parts = sorted(set(parts))
for q in parts:
p = q.query
- if repo.has_product(mpn = p if q.is_mpn else None, dpn = p if not q.is_mpn else None) and not args.force:
- print(color("Already have facts for {}".format(p), "white"))
+ if repo.has_product(mpn=p if q.is_mpn else None, dpn=p if not q.is_mpn else None) and not args.force:
+ log.info("Already have facts for {}".format(p))
continue
- print(color("Searching for {}".format(p), "white"))
+ log.info("Searching for {}".format(p))
response = client.search(p)
todos = []
if response.response_type == SearchResponseTypes.SINGLE:
p = response.products[0]
- print(color("Direct match mpn/dpn: {}/{}".format(p.mpn, p.part_number), "white"))
+ log.info("Direct match mpn/dpn: {}/{}".format(p.mpn, p.part_number))
on_product(p)
elif response.response_type == SearchResponseTypes.MANY:
- hits = [(mpn, list(products)) for mpn, products in groupby(sorted(response.products, key=lambda p: p.mpn), lambda p: p.mpn)]
+ hits = [(mpn, list(products)) for mpn, products in
+ groupby(sorted(response.products, key=lambda p: p.mpn), lambda p: p.mpn)]
if len(hits) == 1:
(mpn, products) = hits[0]
part_number = products[0].part_number
- print(color("Got many results, but they all point to the same part: {}. Will use {} for downloading attributes.".format(mpn, ", ".join([p.part_number for p in products])), "white"))
+ product_strings = ", ".join([p.part_number for p in products])
+ log.info("Got many results, but they all point to the same part: {}. "
+ "Will use {} for downloading attributes.".format(mpn, product_strings))
todos.append(part_number)
else:
for k, g in hits:
- print(color("Got many results with many parts: {}: {}".format(k, list(g)), "white"))
+ log.info("Got many results with many parts: {}: {}".format(k, list(g)))
on_product(list(g)[0])
elif response.response_type == SearchResponseTypes.TOO_MANY:
- print(color("Too many results ({}), select a category first".format(response.count), 'red'))
+ log.warn("Too many results ({}), select a category first".format(response.count))
elif response.response_type == SearchResponseTypes.NO_MATCHES:
- print(color("Part not found", "orange"))
+ log.warn("Part not found")
for part_number in todos:
response = client.search(part_number)
if response.response_type == SearchResponseTypes.SINGLE:
p = response.products[0]
- print(color("Downloaded {}".format(p.mpn), "white"))
+ log.info("Downloaded {}".format(p.mpn))
on_product(p)
else:
- print("Got response of type {} when really expecting a single product.".format(response.response_type))
+ log.warn("Got response of type {} when really expecting a single product.".format(response.response_type))