From c895e6c051cfda77a22b31367cf5c0bbedce4249 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 13 Aug 2017 11:22:07 +0200 Subject: o Going more jupyter. --- .gitignore | 1 + demo/kicad/bom/A64-OlinuXino_Rev_C.xml | 211 ++++- demo/notebooks/BOM Demo.ipynb | 1400 ++++++++++++++++++++++++++++++++ requirements.txt | 5 + src/ee/kicad/bom/__init__.py | 77 +- src/ee/kicad/bom_tool/__init__.py | 110 +++ src/ee/kicad/bom_tool/predef.py | 6 + test/test_bom.py | 41 + test/test_digikey.py | 16 + tox.ini | 3 +- 10 files changed, 1861 insertions(+), 9 deletions(-) create mode 100644 demo/notebooks/BOM Demo.ipynb create mode 100644 src/ee/kicad/bom_tool/__init__.py create mode 100644 src/ee/kicad/bom_tool/predef.py create mode 100644 test/test_digikey.py diff --git a/.gitignore b/.gitignore index 53b822f..3b76ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ demo/*/*.raw demo/*/*.log .tox +.ipynb*/ diff --git a/demo/kicad/bom/A64-OlinuXino_Rev_C.xml b/demo/kicad/bom/A64-OlinuXino_Rev_C.xml index be920c1..39d4006 100644 --- a/demo/kicad/bom/A64-OlinuXino_Rev_C.xml +++ b/demo/kicad/bom/A64-OlinuXino_Rev_C.xml @@ -1,7 +1,12 @@ + - /home/trygvis/dev/com.github/OLIMEX/OLINUXINO/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_C/A64-OlinuXino_Rev_C.sch + /wat/OLIMEX/OLINUXINO/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_C/A64-OlinuXino_Rev_C.sch ma. 07. aug. 2017 kl. 22.36 +0200 Eeschema 4.0.6+dfsg1-1 @@ -64,6 +69,10 @@ 561E4D88 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -71,6 +80,10 @@ 561E4EAA + + 478-1129-2-ND + 0402ZD104KAT2A + 1uF/10V/10% @@ -92,6 +105,10 @@ 561E4E92 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -99,6 +116,10 @@ 561E57FE + + 478-1129-2-ND + 0402ZD104KAT2A + 243R/1% @@ -113,6 +134,10 @@ 561E6CD8 + + 478-1129-2-ND + 0402ZD104KAT2A + 22R @@ -162,6 +187,10 @@ 562050DC + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -169,6 +198,10 @@ 5620575E + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -176,6 +209,10 @@ 56207D58 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -183,6 +220,10 @@ 56208905 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -190,6 +231,10 @@ 5620A865 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -197,6 +242,10 @@ 5620AB64 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -204,6 +253,10 @@ 5620ADAF + + 478-1129-2-ND + 0402ZD104KAT2A + 10uF/6.3V/20% @@ -218,6 +271,10 @@ 5621202A + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -225,6 +282,10 @@ 56212030 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -232,6 +293,10 @@ 56212036 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -239,6 +304,10 @@ 5621203C + + 478-1129-2-ND + 0402ZD104KAT2A + 10uF/6.3V/20% @@ -267,6 +336,10 @@ 56217802 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -274,6 +347,10 @@ 56217880 + + 478-1129-2-ND + 0402ZD104KAT2A + 243R/1% @@ -295,6 +372,10 @@ 5621CFF8 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -302,6 +383,10 @@ 5621CFFE + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -309,6 +394,10 @@ 5621D004 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -316,6 +405,10 @@ 5621D00A + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -323,6 +416,10 @@ 5621D010 + + 478-1129-2-ND + 0402ZD104KAT2A + 10uF/6.3V/20% @@ -337,6 +434,10 @@ 5621D028 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -344,6 +445,10 @@ 5621D02E + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -351,6 +456,10 @@ 5621D034 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -358,6 +467,10 @@ 5621D03A + + 478-1129-2-ND + 0402ZD104KAT2A + 10uF/6.3V/20% @@ -481,6 +594,10 @@ 562677EF + + 478-1129-2-ND + 0402ZD104KAT2A + 1uF/10V/10% @@ -495,6 +612,10 @@ 5624F9D4 + + 587-1819-2-ND + JMK063BJ224MP-F + 100nF/10V/10% @@ -502,6 +623,10 @@ 5624F9CD + + 478-1129-2-ND + 0402ZD104KAT2A + 1uF/10V/10% @@ -516,6 +641,10 @@ 56251915 + + 478-1129-2-ND + 0402ZD104KAT2A + FB0805/600R/2A @@ -586,6 +715,10 @@ 56274CAA + + 478-1129-2-ND + 0402ZD104KAT2A + NA(10k) @@ -677,6 +810,10 @@ 562CBE9C + + 478-1129-2-ND + 0402ZD104KAT2A + 10uF/6.3V/20% @@ -691,6 +828,10 @@ 562D84AB + + 478-1129-2-ND + 0402ZD104KAT2A + 10uF/6.3V/20% @@ -754,6 +895,10 @@ 56299DA1 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -761,6 +906,10 @@ 5629AC30 + + 478-1129-2-ND + 0402ZD104KAT2A + 2k/1% @@ -824,6 +973,10 @@ 562D6A02 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -831,6 +984,10 @@ 562D74CB + + 478-1129-2-ND + 0402ZD104KAT2A + 100k @@ -880,6 +1037,10 @@ 56326ED5 + + 478-1129-2-ND + 0402ZD104KAT2A + 10uF/6.3V/20% @@ -992,6 +1153,10 @@ 57BB8E9B + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -999,6 +1164,10 @@ 57BB8EA1 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -1006,6 +1175,10 @@ 57BBB6F8 + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -1013,6 +1186,10 @@ 57BBB931 + + 478-1129-2-ND + 0402ZD104KAT2A + 33pF/50V/5% @@ -1034,6 +1211,10 @@ 57BC455C + + 478-1129-2-ND + 0402ZD104KAT2A + 100nF/10V/10% @@ -1041,6 +1222,10 @@ 57BC4562 + + 478-1129-2-ND + 0402ZD104KAT2A + TESTPAD @@ -1181,6 +1366,10 @@ 562AFE85 + + 478-1129-2-ND + 0402ZD104KAT2A + MICRO_USB/MISB-SWMM-5B_LF @@ -1216,6 +1405,10 @@ 562A7F62 + + 478-1129-2-ND + 0402ZD104KAT2A + NA(47uF/6.3V/20%) @@ -1265,6 +1458,10 @@ 562C1028 + + 478-1129-2-ND + 0402ZD104KAT2A + 10k @@ -1752,6 +1949,8 @@ Value 1 Value2 Value3 + 587-1819-2-ND + JMK063BJ224MP-F @@ -1819,6 +2018,8 @@ Value 1 Value2 Value3 + 587-1819-2-ND + JMK063BJ224MP-F @@ -1843,6 +2044,8 @@ Value 1 Value2 Value3 + 587-1819-2-ND + JMK063BJ224MP-F @@ -2013,6 +2216,8 @@ Value 1 Value2 Value3 + 587-1819-2-ND + JMK063BJ224MP-F @@ -2049,6 +2254,8 @@ Value 1 Value2 Value3 + 587-1819-2-ND + JMK063BJ224MP-F @@ -4800,7 +5007,7 @@ - /home/trygvis/dev/com.github/OLIMEX/OLINUXINO/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_C/A64-OlinuXino_Rev_C-cache.lib + /wat/OLIMEX/OLINUXINO/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_C/A64-OlinuXino_Rev_C-cache.lib diff --git a/demo/notebooks/BOM Demo.ipynb b/demo/notebooks/BOM Demo.ipynb new file mode 100644 index 0000000..f9d6faa --- /dev/null +++ b/demo/notebooks/BOM Demo.ipynb @@ -0,0 +1,1400 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Notebook configuration" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The autoreload extension is already loaded. To reload it, use:\n", + " %reload_ext autoreload\n" + ] + } + ], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "%aimport ee.kicad.bom\n", + "%aimport ee.kicad.bom.io\n", + "\n", + "from ee.kicad.bom import *\n", + "from ee.kicad.bom.io import read_bom" + ] + }, + { + "cell_type": "code", + "execution_count": 170, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "bom_file = \"../kicad/bom/A64-OlinuXino_Rev_C.xml\"\n", + "bom_file = \"../kicad/bom/gw.xml\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Load the BOM, sort by reference" + ] + }, + { + "cell_type": "code", + "execution_count": 199, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "import os\n", + "import os.path\n", + "import pandas\n", + "\n", + "bom = read_bom(bom_file).to_pandas()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Sort a BOM" + ] + }, + { + "cell_type": "code", + "execution_count": 200, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "f=lambda x: pandas.Series(data=x, index=['ref_name', 'ref_num', 'ref_rest'])\n", + "sort_fields=bom[\"ref\"].map(ee.kicad.bom.split_ref).apply(f)\n", + "\n", + "bom=pandas.concat([bom, sort_fields], axis=1, join_axes=[bom.index])\n", + "bom=bom.sort_values(by=list(sort_fields.columns))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 201, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CapacitanceColorDescriptionFrequencyImpedanceInductanceManufacturerPart NumberResistancerefvalueref_nameref_numref_rest
C11.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC1C0402_1u_10Vdc_X5RC1
C21.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC2C0402_1u_10Vdc_X5RC2
C31.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC3C0402_1u_10Vdc_X5RC3
C41.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC4C0402_1u_10Vdc_X5RC4
C51.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC5C0402_1u_10Vdc_X5RC5
C61.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC6C0402_1u_10Vdc_X5RC6
C71.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC7C0402_1u_10Vdc_X5RC7
C81.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC8C0402_1u_10Vdc_X5RC8
C91.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC9C0402_1u_10Vdc_X5RC9
C104.7uFNone4.7uF, 6.3Vdc, ±20%, X5RNoneNoneNoneMurataGRM185R60J475ME15NoneC10C0603_4u7_6.3Vdc_X5RC10
C114.7uFNone4.7uF, 6.3Vdc, ±20%, X5RNoneNoneNoneMurataGRM185R60J475ME15NoneC11C0603_4u7_6.3Vdc_X5RC11
C124.7uFNone4.7uF, 6.3Vdc, ±20%, X5RNoneNoneNoneMurataGRM185R60J475ME15NoneC12C0603_4u7_6.3Vdc_X5RC12
C131.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC13C0402_1u_10Vdc_X5RC13
C141.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC14C0402_1u_10Vdc_X5RC14
C1510000pFNone10000pF, 10Vdc, ±10%, X5RNoneNoneNoneMurataGRM155R61A103KA01NoneC15C0402_10n_10Vdc_X5RC15
C1610000pFNone10000pF, 10Vdc, ±10%, X5RNoneNoneNoneMurataGRM155R61A103KA01NoneC16C0402_10n_10Vdc_X5RC16
C1710000pFNone10000pF, 10Vdc, ±10%, X5RNoneNoneNoneMurataGRM155R61A103KA01NoneC17C0402_10n_10Vdc_X5RC17
C181.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC18C0402_1u_10Vdc_X5RC18
C191.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC19C0402_1u_10Vdc_X5RC19
C201.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC20C0402_1u_10Vdc_X5RC20
C211.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC21C0402_1u_10Vdc_X5RC21
C2210pFNone10pF, 100Vdc, ±2%, C0GNoneNoneNoneMurataGRM1555C2A100GA01NoneC22C0402_10p_100Vdc_C0GC22
C2310pFNone10pF, 100Vdc, ±2%, C0GNoneNoneNoneMurataGRM1555C2A100GA01NoneC23C0402_10p_100Vdc_C0GC23
C2410pFNone10pF, 100Vdc, ±2%, C0GNoneNoneNoneMurataGRM1555C2A100GA01NoneC24C0402_10p_100Vdc_C0GC24
C2510pFNone10pF, 100Vdc, ±2%, C0GNoneNoneNoneMurataGRM1555C2A100GA01NoneC25C0402_10p_100Vdc_C0GC25
C2610pFNone10pF, 100Vdc, ±2%, C0GNoneNoneNoneMurataGRM1555C2A100GA01NoneC26C0402_10p_100Vdc_C0GC26
C271.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC27C0402_1u_10Vdc_X5RC27
C2815pFNone15pF, 100Vdc, ±2%, C0GNoneNoneNoneMurataGRM1555C2A150GA01NoneC28C0402_15p_100Vdc_C0GC28
C291.0uFNone1.0uF, 10Vdc, ±20%, X5RNoneNoneNoneMurataGRM153R61A105ME95NoneC29C0402_1u_10Vdc_X5RC29
C3015pFNone15pF, 100Vdc, ±2%, C0GNoneNoneNoneMurataGRM1555C2A150GA01NoneC30C0402_15p_100Vdc_C0GC30
.............................................
R32NoneNone1.5k, ±1%, 0.063WNoneNoneNoneVishayCRCW04021K50FKED1.5kR32R0402_1k50R32
R33NoneNone10k, ±1%, 0.063WNoneNoneNoneVishayCRCW040210K0FKED10kR33R0402_10kR33
R34NoneNone330, ±1%, 0.063WNoneNoneNoneVishayCRCW0402330RFKED330R34R0402_330RR34
R35NoneNone330, ±1%, 0.063WNoneNoneNoneVishayCRCW0402330RFKED330R35R0402_330RR35
R36NoneNone10k, ±1%, 0.063WNoneNoneNoneVishayCRCW040210K0FKED10kR36R0402_10kR36
R37NoneNone100k, ±1%, 0.063WNoneNoneNoneVishayCRCW0402100KFKED100kR37R0402_100kR37
R38NoneNone100k, ±1%, 0.063WNoneNoneNoneVishayCRCW0402100KFKED100kR38R0402_100kR38
R39NoneNone100k, ±1%, 0.063WNoneNoneNoneVishayCRCW0402100KFKED100kR39R0402_100kR39
R40NoneNone100, ±1%, 0.063WNoneNoneNoneVishayCRCW0402100RFKED100R40R0402_100RR40
R41NoneNone100, ±1%, 0.063WNoneNoneNoneVishayCRCW0402100RFKED100R41R0402_100RR41
R42NoneNone39, ±1%, 0.063WNoneNoneNoneVishayCRCW040239R0FKED39R42R0402_39RR42
R43NoneNone39, ±1%, 0.063WNoneNoneNoneVishayCRCW040239R0FKED39R43R0402_39RR43
R44NoneNone10k, ±1%, 0.063WNoneNoneNoneVishayCRCW040210K0FKED10kR44R0402_10kR44
T1NoneNoneNoneNoneNoneNoneNoneNoneNoneT1S558-5999-T7-FT1
U1NoneNoneNoneNoneNoneNoneNoneNoneNoneU1AT91SAM9G25U1
U2NoneNoneNoneNoneNoneNoneNoneNoneNoneU2USBLC6-4U2
U3NoneNoneNoneNoneNoneNoneNoneNoneNoneU3CC2520U3
U4NoneNoneNoneNoneNoneNoneNoneNoneNoneU4NCP360SNAET1GU4
U5NoneNoneNoneNoneNoneNoneNoneNoneNoneU5TPS62742U5
U6NoneNoneNoneNoneNoneNoneNoneNoneNoneU6MIC23254U6
U7NoneNoneNoneNoneNoneNoneNoneNoneNoneU7IS46DR16640BU7
U8NoneNoneNoneNoneNoneNoneNoneNoneNoneU8MX30LF1G08AAU8
U9NoneNoneNoneNoneNoneNoneNoneNoneNoneU9LAN8710U9
U10NoneNoneNoneNoneNoneNoneNoneNoneNoneU10USBLC6-4U10
U11NoneNoneNoneNoneNoneNoneNoneNoneNoneU11LP3470M5-3.08U11
X1NoneNonef=12MHz, Stability:±150ppm, Tol:±50ppm,Load ca...12MHzNoneNoneNDKNX3225GA-12.000M-STD-CRA-1NoneX1NX3225GA-12.000M-STD-CRA-1X1
X2NoneNonef=32.768kHz, Stability:-, Tol:±20ppm,Load capa...32.768kHzNoneNoneNDKNX2012SA-32.768K-STD-MUB-1NoneX2NX2012SA-32.768K-STD-MUB-1X2
X3NoneNonef=32MHz, Stability:±10ppm, Tol:±10ppm,Load cap...32MHzNoneNoneNDKNX2520SA-32.000000MHZNoneX3NX2520SA-32.000000MHZX3
X4NoneNonef=25MHz, Stability:±25ppm, Tol:±15ppm,Load cap...25MHzNoneNoneNDKNX2520SA-25.000M-STD-CSW-5NoneX4NX2520SA-25.000M-STD-CSW-5X4
Z1NoneNoneNoneNoneNoneNoneNoneNoneNoneZ1WLA.01Z1
\n", + "

165 rows × 14 columns

\n", + "
" + ], + "text/plain": [ + " Capacitance Color Description \\\n", + "C1 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C2 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C3 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C4 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C5 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C6 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C7 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C8 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C9 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C10 4.7uF None 4.7uF, 6.3Vdc, ±20%, X5R \n", + "C11 4.7uF None 4.7uF, 6.3Vdc, ±20%, X5R \n", + "C12 4.7uF None 4.7uF, 6.3Vdc, ±20%, X5R \n", + "C13 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C14 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C15 10000pF None 10000pF, 10Vdc, ±10%, X5R \n", + "C16 10000pF None 10000pF, 10Vdc, ±10%, X5R \n", + "C17 10000pF None 10000pF, 10Vdc, ±10%, X5R \n", + "C18 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C19 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C20 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C21 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C22 10pF None 10pF, 100Vdc, ±2%, C0G \n", + "C23 10pF None 10pF, 100Vdc, ±2%, C0G \n", + "C24 10pF None 10pF, 100Vdc, ±2%, C0G \n", + "C25 10pF None 10pF, 100Vdc, ±2%, C0G \n", + "C26 10pF None 10pF, 100Vdc, ±2%, C0G \n", + "C27 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C28 15pF None 15pF, 100Vdc, ±2%, C0G \n", + "C29 1.0uF None 1.0uF, 10Vdc, ±20%, X5R \n", + "C30 15pF None 15pF, 100Vdc, ±2%, C0G \n", + ".. ... ... ... \n", + "R32 None None 1.5k, ±1%, 0.063W \n", + "R33 None None 10k, ±1%, 0.063W \n", + "R34 None None 330, ±1%, 0.063W \n", + "R35 None None 330, ±1%, 0.063W \n", + "R36 None None 10k, ±1%, 0.063W \n", + "R37 None None 100k, ±1%, 0.063W \n", + "R38 None None 100k, ±1%, 0.063W \n", + "R39 None None 100k, ±1%, 0.063W \n", + "R40 None None 100, ±1%, 0.063W \n", + "R41 None None 100, ±1%, 0.063W \n", + "R42 None None 39, ±1%, 0.063W \n", + "R43 None None 39, ±1%, 0.063W \n", + "R44 None None 10k, ±1%, 0.063W \n", + "T1 None None None \n", + "U1 None None None \n", + "U2 None None None \n", + "U3 None None None \n", + "U4 None None None \n", + "U5 None None None \n", + "U6 None None None \n", + "U7 None None None \n", + "U8 None None None \n", + "U9 None None None \n", + "U10 None None None \n", + "U11 None None None \n", + "X1 None None f=12MHz, Stability:±150ppm, Tol:±50ppm,Load ca... \n", + "X2 None None f=32.768kHz, Stability:-, Tol:±20ppm,Load capa... \n", + "X3 None None f=32MHz, Stability:±10ppm, Tol:±10ppm,Load cap... \n", + "X4 None None f=25MHz, Stability:±25ppm, Tol:±15ppm,Load cap... \n", + "Z1 None None None \n", + "\n", + " Frequency Impedance Inductance Manufacturer Part Number \\\n", + "C1 None None None Murata GRM153R61A105ME95 \n", + "C2 None None None Murata GRM153R61A105ME95 \n", + "C3 None None None Murata GRM153R61A105ME95 \n", + "C4 None None None Murata GRM153R61A105ME95 \n", + "C5 None None None Murata GRM153R61A105ME95 \n", + "C6 None None None Murata GRM153R61A105ME95 \n", + "C7 None None None Murata GRM153R61A105ME95 \n", + "C8 None None None Murata GRM153R61A105ME95 \n", + "C9 None None None Murata GRM153R61A105ME95 \n", + "C10 None None None Murata GRM185R60J475ME15 \n", + "C11 None None None Murata GRM185R60J475ME15 \n", + "C12 None None None Murata GRM185R60J475ME15 \n", + "C13 None None None Murata GRM153R61A105ME95 \n", + "C14 None None None Murata GRM153R61A105ME95 \n", + "C15 None None None Murata GRM155R61A103KA01 \n", + "C16 None None None Murata GRM155R61A103KA01 \n", + "C17 None None None Murata GRM155R61A103KA01 \n", + "C18 None None None Murata GRM153R61A105ME95 \n", + "C19 None None None Murata GRM153R61A105ME95 \n", + "C20 None None None Murata GRM153R61A105ME95 \n", + "C21 None None None Murata GRM153R61A105ME95 \n", + "C22 None None None Murata GRM1555C2A100GA01 \n", + "C23 None None None Murata GRM1555C2A100GA01 \n", + "C24 None None None Murata GRM1555C2A100GA01 \n", + "C25 None None None Murata GRM1555C2A100GA01 \n", + "C26 None None None Murata GRM1555C2A100GA01 \n", + "C27 None None None Murata GRM153R61A105ME95 \n", + "C28 None None None Murata GRM1555C2A150GA01 \n", + "C29 None None None Murata GRM153R61A105ME95 \n", + "C30 None None None Murata GRM1555C2A150GA01 \n", + ".. ... ... ... ... ... \n", + "R32 None None None Vishay CRCW04021K50FKED \n", + "R33 None None None Vishay CRCW040210K0FKED \n", + "R34 None None None Vishay CRCW0402330RFKED \n", + "R35 None None None Vishay CRCW0402330RFKED \n", + "R36 None None None Vishay CRCW040210K0FKED \n", + "R37 None None None Vishay CRCW0402100KFKED \n", + "R38 None None None Vishay CRCW0402100KFKED \n", + "R39 None None None Vishay CRCW0402100KFKED \n", + "R40 None None None Vishay CRCW0402100RFKED \n", + "R41 None None None Vishay CRCW0402100RFKED \n", + "R42 None None None Vishay CRCW040239R0FKED \n", + "R43 None None None Vishay CRCW040239R0FKED \n", + "R44 None None None Vishay CRCW040210K0FKED \n", + "T1 None None None None None \n", + "U1 None None None None None \n", + "U2 None None None None None \n", + "U3 None None None None None \n", + "U4 None None None None None \n", + "U5 None None None None None \n", + "U6 None None None None None \n", + "U7 None None None None None \n", + "U8 None None None None None \n", + "U9 None None None None None \n", + "U10 None None None None None \n", + "U11 None None None None None \n", + "X1 12MHz None None NDK NX3225GA-12.000M-STD-CRA-1 \n", + "X2 32.768kHz None None NDK NX2012SA-32.768K-STD-MUB-1 \n", + "X3 32MHz None None NDK NX2520SA-32.000000MHZ \n", + "X4 25MHz None None NDK NX2520SA-25.000M-STD-CSW-5 \n", + "Z1 None None None None None \n", + "\n", + " Resistance ref value ref_name ref_num ref_rest \n", + "C1 None C1 C0402_1u_10Vdc_X5R C 1 \n", + "C2 None C2 C0402_1u_10Vdc_X5R C 2 \n", + "C3 None C3 C0402_1u_10Vdc_X5R C 3 \n", + "C4 None C4 C0402_1u_10Vdc_X5R C 4 \n", + "C5 None C5 C0402_1u_10Vdc_X5R C 5 \n", + "C6 None C6 C0402_1u_10Vdc_X5R C 6 \n", + "C7 None C7 C0402_1u_10Vdc_X5R C 7 \n", + "C8 None C8 C0402_1u_10Vdc_X5R C 8 \n", + "C9 None C9 C0402_1u_10Vdc_X5R C 9 \n", + "C10 None C10 C0603_4u7_6.3Vdc_X5R C 10 \n", + "C11 None C11 C0603_4u7_6.3Vdc_X5R C 11 \n", + "C12 None C12 C0603_4u7_6.3Vdc_X5R C 12 \n", + "C13 None C13 C0402_1u_10Vdc_X5R C 13 \n", + "C14 None C14 C0402_1u_10Vdc_X5R C 14 \n", + "C15 None C15 C0402_10n_10Vdc_X5R C 15 \n", + "C16 None C16 C0402_10n_10Vdc_X5R C 16 \n", + "C17 None C17 C0402_10n_10Vdc_X5R C 17 \n", + "C18 None C18 C0402_1u_10Vdc_X5R C 18 \n", + "C19 None C19 C0402_1u_10Vdc_X5R C 19 \n", + "C20 None C20 C0402_1u_10Vdc_X5R C 20 \n", + "C21 None C21 C0402_1u_10Vdc_X5R C 21 \n", + "C22 None C22 C0402_10p_100Vdc_C0G C 22 \n", + "C23 None C23 C0402_10p_100Vdc_C0G C 23 \n", + "C24 None C24 C0402_10p_100Vdc_C0G C 24 \n", + "C25 None C25 C0402_10p_100Vdc_C0G C 25 \n", + "C26 None C26 C0402_10p_100Vdc_C0G C 26 \n", + "C27 None C27 C0402_1u_10Vdc_X5R C 27 \n", + "C28 None C28 C0402_15p_100Vdc_C0G C 28 \n", + "C29 None C29 C0402_1u_10Vdc_X5R C 29 \n", + "C30 None C30 C0402_15p_100Vdc_C0G C 30 \n", + ".. ... ... ... ... ... ... \n", + "R32 1.5k R32 R0402_1k50 R 32 \n", + "R33 10k R33 R0402_10k R 33 \n", + "R34 330 R34 R0402_330R R 34 \n", + "R35 330 R35 R0402_330R R 35 \n", + "R36 10k R36 R0402_10k R 36 \n", + "R37 100k R37 R0402_100k R 37 \n", + "R38 100k R38 R0402_100k R 38 \n", + "R39 100k R39 R0402_100k R 39 \n", + "R40 100 R40 R0402_100R R 40 \n", + "R41 100 R41 R0402_100R R 41 \n", + "R42 39 R42 R0402_39R R 42 \n", + "R43 39 R43 R0402_39R R 43 \n", + "R44 10k R44 R0402_10k R 44 \n", + "T1 None T1 S558-5999-T7-F T 1 \n", + "U1 None U1 AT91SAM9G25 U 1 \n", + "U2 None U2 USBLC6-4 U 2 \n", + "U3 None U3 CC2520 U 3 \n", + "U4 None U4 NCP360SNAET1G U 4 \n", + "U5 None U5 TPS62742 U 5 \n", + "U6 None U6 MIC23254 U 6 \n", + "U7 None U7 IS46DR16640B U 7 \n", + "U8 None U8 MX30LF1G08AA U 8 \n", + "U9 None U9 LAN8710 U 9 \n", + "U10 None U10 USBLC6-4 U 10 \n", + "U11 None U11 LP3470M5-3.08 U 11 \n", + "X1 None X1 NX3225GA-12.000M-STD-CRA-1 X 1 \n", + "X2 None X2 NX2012SA-32.768K-STD-MUB-1 X 2 \n", + "X3 None X3 NX2520SA-32.000000MHZ X 3 \n", + "X4 None X4 NX2520SA-25.000M-STD-CSW-5 X 4 \n", + "Z1 None Z1 WLA.01 Z 1 \n", + "\n", + "[165 rows x 14 columns]" + ] + }, + "execution_count": 201, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bom" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.4rc1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/requirements.txt b/requirements.txt index d338937..627079e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,8 @@ matplotlib==2.0.2 pandas==0.20.3 Pillow==4.2.1 pytest==3.2.0 + +mypy==0.521; python_version >= '3.0' + +# for development +jupyter==1.0.0 diff --git a/src/ee/kicad/bom/__init__.py b/src/ee/kicad/bom/__init__.py index 1808357..d0798a4 100644 --- a/src/ee/kicad/bom/__init__.py +++ b/src/ee/kicad/bom/__init__.py @@ -1,10 +1,34 @@ +import re +import sys + __all__ = [ 'Part', 'Library', 'Bom', 'Comp', + 'split_ref', ] +def split_ref(ref): + """Split "C12" into a tuple that's useful for sorting by component reference. + + For example: "C12" => ("C", 12, None). "Cfoo" => ("C", sys.maxsize, ""). + """ + m = split_ref.r.match(ref) + if not m: + return (ref, sys.maxsize, "") + groups = m.groups() + ref = groups[0] + val = groups[1] + rest = groups[2] + try: + return (ref, int(val), rest) + except ValueError: + pass + + return (ref, val, rest) +split_ref.r = re.compile("([A-Za-z]+)([0-9]+)(.*)") + class Part: def __init__(self, name): self.name = name @@ -22,19 +46,26 @@ class Library: self.parts[part] = p return p -class Bom: +class Bom(object): def __init__(self): self.libraries = {} - self.components = {} + self._components = {} def add_component(self, component): - self.components[component.ref] = component + self._components[component.ref] = component def get_component(self, name): - return self.components[name] + return self._components[name] def get_components(self): - return self.components + return self._components + + def all_field_names(self): + fields = set(['ref', 'value']) + for c in self._components.values(): + for f in c.fields: + fields.add(f) + return fields def find_library(self, name): try: @@ -44,6 +75,27 @@ class Bom: self.libraries[name] = lib return lib + def to_pandas(self, ref_field_name = None, value_field_name = None): + import pandas + + ref_field_name = ref_field_name or "ref" + value_field_name = value_field_name or "value" + + fields = self.all_field_names() + data = {k: [] for k in fields} + refs = [] + values = [] + for ref, c in self.get_components().items(): + refs.append(c.ref) + values.append(c.value) + 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) + class Comp: def __init__(self, ref, value, library, part, footprint): self.ref = ref @@ -56,3 +108,18 @@ class Comp: def add_field(self, key, value): self.fields[key] = value + def __contains__(self, key): + if key == 'ref': + return self.ref is not None + elif key == 'value': + return self.value is not None + else: + return key in self.fields + + def __getitem__(self, key): + if key == 'ref': + return self.ref + elif key == 'value': + return self.value + else: + return self.fields[key] diff --git a/src/ee/kicad/bom_tool/__init__.py b/src/ee/kicad/bom_tool/__init__.py new file mode 100644 index 0000000..9f450c9 --- /dev/null +++ b/src/ee/kicad/bom_tool/__init__.py @@ -0,0 +1,110 @@ +from ee.kicad.bom import * +import functools +import itertools +import pandas as pd + +def _none_if_empty(l): + return l if l is not None and len(l) > 0 else None + +class Supplier(): + def __init__(self, name, bom_field = None): + self._name = name + self._bom_field = bom_field if not None else name + + @property + def bom_field(self): + return self._bom_field + +class Settings(): + def __init__(self, suppliers = None, part_field = None): + self._suppliers = suppliers if suppliers is not None else [] + self._part_field = part_field if part_field is not None else 'part' + + @property + def suppliers(self): + return self._suppliers + + @property + def part_field(self): + return self._part_field + + @part_field.setter + def part_field(self, value): + self._part_field = value + +class CsvFormat(): + def __init__(self, supplier = None, group_by_fields = None, required_fields = None): + self._supplier = supplier + self._group_by_fields = _none_if_empty(group_by_fields) + self._required_fields = _none_if_empty(required_fields) + + @property + def supplier(self): + return self._supplier + + @property + def group_by_fields(self): + return self._group_by_fields + + @property + def required_fields(self): + return self._required_fields + +def _all(fs, c): + for f in fs: + if not f(c): + return False + return True + +def to_panda(bom, bom_settings, csv_format): # type: (Bom, BomSettings, CsvFormat) -> None + filters = [] + + print("csv_format.supplier.bom_field={}".format(csv_format.supplier.bom_field)) + if csv_format.supplier is not None: + filters.append(lambda c: csv_format.supplier.bom_field in c) + + if csv_format.group_by_fields is not None: + filters.append(lambda c: all([field in c for field in csv_format.group_by_fields])) + + if csv_format.required_fields is not None: + filters.append(lambda c: all([field in c for field in csv_format.required_fields])) + + f = functools.partial(_all, filters) + print("len(filters)={}".format(len(filters))) + print("len(bom.get_components())={}".format(len(bom.get_components()))) + + filtered = [c for ref, c in bom.get_components().items() if f(c)] + print("filtered:, len={}".format(len(filtered))) + filtered.sort(key=lambda c: c.ref) + print("sorted filtered:, len={}".format(len(filtered))) + + counts=None + parts=[] + + frame = {} + for n in bom.all_field_names(): + frame[n] = [] + + if csv_format.group_by_fields is not None: + counts, parts, refs=([],[],[]) + for group, comps in itertools.groupby(filtered, key=lambda c: [field for field in c for c in csv_format.group_by_fields]): + gs = list(group) + cs = list(comps) +# counts.append(len(cs)) +# dpns.append(part) +# mpns.append(part) +# 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, +# }) + else: + for ref, c in filtered: + for key, value in c: + frame[key] = value + + return pd.DataFrame(data=frame) diff --git a/src/ee/kicad/bom_tool/predef.py b/src/ee/kicad/bom_tool/predef.py new file mode 100644 index 0000000..717f6d3 --- /dev/null +++ b/src/ee/kicad/bom_tool/predef.py @@ -0,0 +1,6 @@ +from ee.kicad.bom_tool import * + +digikey = Supplier('Digi-Key', bom_field = 'digikey') + +def digikeyCsvFormat(digikey_supplier): + return CsvFormat(supplier = digikey, group_by_fields = [digikey_supplier.bom_field]) diff --git a/test/test_bom.py b/test/test_bom.py index 1a54a9e..6da7798 100644 --- a/test/test_bom.py +++ b/test/test_bom.py @@ -1,11 +1,22 @@ import pytest import os.path +import sys from ee.kicad.bom import * from ee.kicad.bom.io import read_bom basedir = os.path.dirname(os.path.abspath(__file__)) +@pytest.mark.parametrize("s, ref, val, rest", [ + ("C12", "C", 12, ""), + ("C12n", "C", 12, "n"), + ("C", "C", sys.maxsize, ""), + ("Foo", "Foo", sys.maxsize, ""), + ("+3.0VA1", "+3.0VA1", sys.maxsize, ""), + ]) +def test_split_ref(s, ref, val, rest): + assert split_ref(s) == (ref, val, rest) + def test_read_bom_1(): bom = read_bom(basedir + '/../demo/kicad/bom/A64-OlinuXino_Rev_C.xml') assert len(bom.get_components()) == 425 @@ -17,7 +28,37 @@ def test_read_bom_2(): r5 = bom.get_component("R5") assert r5.ref == "R5" assert r5.value == "R0402_100R" + assert r5["value"] == "R0402_100R" assert r5.footprint == "Resistors_SMD:R_0402" assert r5.library.name == "gw-cache" assert len(r5.fields) == 4 assert r5.fields["Part Number"] == "CRCW0402100RFKED" + assert r5["Part Number"] == "CRCW0402100RFKED" + assert set(['ref', 'value', 'Capacitance', 'Color', 'Description', 'Frequency', 'Impedance', 'Inductance', 'Manufacturer', 'Part Number', 'Resistance']) == bom.all_field_names() + + assert not "foo" in r5 + with pytest.raises(KeyError): + r5["foo"] + +def test_read_bom_2_pandas(): + bom = read_bom(basedir + '/../demo/kicad/bom/gw.xml').to_pandas() + assert len(bom) == 165 + + print("bom") + print(str(bom)) + r5 = bom.loc["R5"] + print(str(r5.index)) +# assert r5.index == "R5" + assert r5["ref"] == "R5" + assert r5["value"] == "R0402_100R" + assert r5["value"] == "R0402_100R" +# assert r5["footprint"] == "Resistors_SMD:R_0402" +# assert r5.library.name == "gw-cache" +# assert len(r5.fields) == 4 +# assert r5.fields["Part Number"] == "CRCW0402100RFKED" + assert r5["Part Number"] == "CRCW0402100RFKED" +# assert set(['ref', 'value', 'Capacitance', 'Color', 'Description', 'Frequency', 'Impedance', 'Inductance', 'Manufacturer', 'Part Number', 'Resistance']) == bom.all_field_names() + + assert not "foo" in r5 + with pytest.raises(KeyError): + r5["foo"] diff --git a/test/test_digikey.py b/test/test_digikey.py new file mode 100644 index 0000000..148f56e --- /dev/null +++ b/test/test_digikey.py @@ -0,0 +1,16 @@ +from ee.kicad.bom import * +from ee.kicad.bom.io import read_bom +import ee.kicad.bom_tool as bom_tool +import ee.kicad.bom_tool.predef as predef +import os.path +import pytest + +basedir = os.path.dirname(os.path.abspath(__file__)) + +@pytest.mark.skip(reason="disabled for now") +def test_digikey(): + print("") + bom = read_bom(basedir + '/../demo/kicad/bom/A64-OlinuXino_Rev_C.xml') + settings = bom_tool.Settings(suppliers = [predef.digikey]) + pd = bom_tool.to_panda(bom, settings, predef.digikeyCsvFormat(predef.digikey)) + print(pd.to_csv(index = False)) diff --git a/tox.ini b/tox.ini index 2fc2fe3..8967df8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,7 @@ [testenv] changedir=test deps= - pytest - numpy + -rrequirements.txt commands= pytest \ --basetemp={envtmpdir} \ -- cgit v1.2.3