├── .coveragerc ├── .github └── workflows │ └── test_deploy.yaml ├── .gitignore ├── LICENSE ├── README.md ├── images ├── doc │ ├── digikey_api_approval_request.png │ ├── digikey_api_approval_request2.png │ ├── kintree_v1_example.png │ ├── kintree_v1_preview.png │ ├── kintree_v1_search_example.png │ └── kintree_v1_settings_user.png ├── logo.png └── python_versions.svg ├── invoke.yaml ├── kintree ├── __init__.py ├── common │ ├── part_tools.py │ ├── progress.py │ └── tools.py ├── config │ ├── automationdirect │ │ ├── automationdirect_api.yaml │ │ └── automationdirect_config.yaml │ ├── config_interface.py │ ├── digikey │ │ ├── digikey_api.yaml │ │ ├── digikey_categories.yaml │ │ └── digikey_config.yaml │ ├── element14 │ │ ├── element14_api.yaml │ │ └── element14_config.yaml │ ├── inventree │ │ ├── categories.yaml │ │ ├── inventree_dev.yaml │ │ ├── inventree_prod.yaml │ │ ├── parameters.yaml │ │ ├── parameters_filters.yaml │ │ ├── stock_locations.yaml │ │ ├── supplier_parameters.yaml │ │ └── suppliers.yaml │ ├── jameco │ │ ├── jameco_api.yaml │ │ └── jameco_config.yaml │ ├── kicad │ │ ├── kicad.yaml │ │ └── kicad_map.yaml │ ├── lcsc │ │ ├── lcsc_api.yaml │ │ └── lcsc_config.yaml │ ├── mouser │ │ ├── mouser_api.yaml │ │ └── mouser_config.yaml │ ├── settings.py │ ├── tme │ │ ├── tme_api.yaml │ │ └── tme_config.yaml │ └── user │ │ ├── general.yaml │ │ ├── internal_part_number.yaml │ │ └── search_api.yaml ├── database │ ├── inventree_api.py │ └── inventree_interface.py ├── gui │ ├── gui.py │ ├── logo.ico │ └── views │ │ ├── common.py │ │ ├── main.py │ │ └── settings.py ├── kicad │ ├── kicad_interface.py │ ├── kicad_symbol.py │ ├── templates │ │ ├── LICENSE │ │ ├── capacitor-polarized.kicad_sym │ │ ├── capacitor.kicad_sym │ │ ├── connector.kicad_sym │ │ ├── crystal-2p.kicad_sym │ │ ├── default.kicad_sym │ │ ├── diode-led.kicad_sym │ │ ├── diode-schottky.kicad_sym │ │ ├── diode-standard.kicad_sym │ │ ├── diode-zener.kicad_sym │ │ ├── eeprom-sot23.kicad_sym │ │ ├── ferrite-bead.kicad_sym │ │ ├── fuse.kicad_sym │ │ ├── inductor.kicad_sym │ │ ├── integrated-circuit.kicad_sym │ │ ├── library_template.kicad_sym │ │ ├── oscillator-4p.kicad_sym │ │ ├── protection-unidir.kicad_sym │ │ ├── resistor-sm.kicad_sym │ │ ├── resistor.kicad_sym │ │ ├── transistor-nfet.kicad_sym │ │ ├── transistor-npn.kicad_sym │ │ ├── transistor-pfet.kicad_sym │ │ └── transistor-pnp.kicad_sym │ └── templates_project │ │ ├── templates_project.kicad_pcb │ │ ├── templates_project.kicad_prl │ │ ├── templates_project.kicad_pro │ │ └── templates_project.kicad_sch ├── kintree_gui.py ├── search │ ├── automationdirect_api.py │ ├── digikey_api.py │ ├── element14_api.py │ ├── jameco_api.py │ ├── lcsc_api.py │ ├── mouser_api.py │ ├── search_api.py │ ├── snapeda_api.py │ └── tme_api.py └── setup_inventree.py ├── kintree_gui.py ├── poetry.lock ├── poetry.toml ├── pyproject.toml ├── requirements.txt ├── run_tests.py ├── setup.cfg ├── tasks.py └── tests ├── files ├── FOOTPRINTS │ └── RF.pretty │ │ ├── Skyworks_SKY13575_639LF.kicad_mod │ │ └── Skyworks_SKY65404-31.kicad_mod ├── SYMBOLS │ └── TEST.kicad_sym ├── digikey_config.yaml ├── inventree_default_db.sqlite3 ├── inventree_dev.yaml ├── kicad_map.yaml └── results.tgz └── test_samples.yaml /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = 3 | # Do not run coverage on environment files 4 | *env* 5 | # Skip GUI coverage 6 | kintree/kintree_gui.py 7 | kintree/gui/* 8 | kintree/common/progress.py 9 | # Skip test script 10 | run_tests.py -------------------------------------------------------------------------------- /.github/workflows/test_deploy.yaml: -------------------------------------------------------------------------------- 1 | name: tests | linting | publishing 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | tags: 8 | - "*.*.*" 9 | paths-ignore: 10 | - README.md 11 | - images/** 12 | pull_request: 13 | branches: 14 | - main 15 | 16 | jobs: 17 | style: 18 | name: Style checks 19 | runs-on: ubuntu-latest 20 | 21 | strategy: 22 | matrix: 23 | python-version: ['3.9', '3.10', '3.11', '3.12'] 24 | 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v2 28 | - name: set up python ${{ matrix.python-version }} 29 | uses: actions/setup-python@v2 30 | with: 31 | python-version: ${{ matrix.python-version }} 32 | - name: Install dependencies 33 | run: | 34 | pip install -U flake8 invoke 35 | - name: PEP checks 36 | run: > 37 | invoke style 38 | 39 | tests: 40 | name: Integration tests 41 | 42 | runs-on: ubuntu-latest 43 | env: 44 | INVENTREE_DB_ENGINE: django.db.backends.sqlite3 45 | INVENTREE_DB_NAME: ${{ github.workspace }}/InvenTree/inventree_default_db.sqlite3 46 | INVENTREE_MEDIA_ROOT: ${{ github.workspace }}/InvenTree 47 | INVENTREE_STATIC_ROOT: ${{ github.workspace }}/InvenTree/static 48 | INVENTREE_BACKUP_DIR: ${{ github.workspace }}/InvenTree/backup 49 | INVENTREE_ENV: 0 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | TOKEN_DIGIKEY: ${{ secrets.TOKEN_DIGIKEY }} 52 | DIGIKEY_CLIENT_ID: ${{ secrets.DIGIKEY_CLIENT_ID }} 53 | DIGIKEY_CLIENT_SECRET: ${{ secrets.DIGIKEY_CLIENT_SECRET }} 54 | DIGIKEY_LOCAL_SITE: US 55 | DIGIKEY_LOCAL_LANGUAGE: en 56 | DIGIKEY_LOCAL_CURRENCY: USD 57 | TME_API_TOKEN: ${{ secrets.TME_API_TOKEN }} 58 | TME_API_SECRET: ${{ secrets.TME_API_SECRET }} 59 | 60 | continue-on-error: true 61 | strategy: 62 | matrix: 63 | python-version: ['3.9', '3.10', '3.11', '3.12'] 64 | 65 | steps: 66 | - name: Checkout code 67 | uses: actions/checkout@v2 68 | - name: Set up Python ${{ matrix.python-version }} 69 | uses: actions/setup-python@v2 70 | with: 71 | python-version: ${{ matrix.python-version }} 72 | - name: Install dependencies 73 | run: | 74 | sudo apt install sqlite3 75 | pip install -U pip invoke coveralls 76 | - name: InvenTree setup 77 | run: | 78 | git clone https://github.com/inventree/InvenTree/ 79 | mkdir InvenTree/static 80 | cp tests/files/inventree_default_db.sqlite3 InvenTree/ 81 | cd InvenTree/ && git switch stable && invoke install && invoke migrate && cd - 82 | - name: Ki-nTree setup 83 | run: | 84 | invoke install 85 | mkdir -p ~/.config/kintree/user/ && mkdir -p ~/.config/kintree/cache/search/ 86 | cp tests/files/inventree_dev.yaml ~/.config/kintree/user/ 87 | cp tests/files/kicad_map.yaml ~/.config/kintree/user/ 88 | cp tests/files/digikey_config.yaml ~/.config/kintree/user/ 89 | cp tests/files/results.tgz ~/.config/kintree/cache/search/ 90 | cd ~/.config/kintree/cache/search/ && tar xvf results.tgz && cd - 91 | - name: GUI test 92 | run: | 93 | python kintree_gui.py b > gui.log 2>&1 & 94 | sleep 2 95 | cat gui.log 96 | export len_log=$(cat gui.log | wc -l) 97 | [[ ${len_log} -eq 0 ]] && true || false 98 | - name: Setup Digi-Key token 99 | if: ${{ github.ref == 'refs/heads/main' || github.event.pull_request.head.repo.full_name == 'sparkmicro/Ki-nTree' }} 100 | run: | 101 | git clone https://$TOKEN_DIGIKEY@github.com/eeintech/digikey-token.git 102 | cd digikey-token/ 103 | python digikey_token_refresh.py 104 | git config --global user.email "kintree@github.actions" 105 | git config --global user.name "Ki-nTree Github Actions" 106 | git add -u 107 | git diff-index --quiet HEAD || git commit -m "Update token" 108 | git push origin master 109 | cp token_storage.json ~/.config/kintree/cache/ 110 | dk_token=$(cat ~/.config/kintree/cache/token_storage.json) 111 | echo -e "Digi-Key Token: $dk_token\n" 112 | cd .. 113 | - name: Run tests 114 | if: ${{ github.ref == 'refs/heads/main' || github.event.pull_request.head.repo.full_name == 'sparkmicro/Ki-nTree' }} 115 | run: | 116 | invoke test -e 1 117 | env: 118 | MOUSER_PART_API_KEY: ${{ secrets.MOUSER_PART_API_KEY }} 119 | ELEMENT14_PART_API_KEY: ${{ secrets.ELEMENT14_PART_API_KEY }} 120 | - name: Run tests (skip APIs) 121 | if: ${{ github.ref != 'refs/heads/main' && github.event.pull_request.head.repo.full_name != 'sparkmicro/Ki-nTree' }} 122 | run: | 123 | invoke test -e 0 124 | - name: Coveralls 125 | if: ${{ github.ref == 'refs/heads/main' || github.event.pull_request.head.repo.full_name == 'sparkmicro/Ki-nTree' }} 126 | run: | 127 | coveralls --version 128 | coveralls --service=github 129 | - name: Run build 130 | run: | 131 | invoke build 132 | 133 | test-publish: 134 | name: Publish to Test PyPI, then PyPI 135 | if: startsWith(github.ref, 'refs/tags/') 136 | runs-on: ubuntu-latest 137 | needs: 138 | - style 139 | - tests 140 | steps: 141 | - name: Checkout code 142 | uses: actions/checkout@v2 143 | - name: Alter the version in pyproject.toml and overwrite __version__ 144 | run: > 145 | GTAG=$(echo $REF | sed -e 's#.*/##') && 146 | sed 147 | --in-place 148 | --expression 149 | "s/version = \".*\" # placeholder/version = \"$GTAG\"/g" 150 | pyproject.toml 151 | && echo "__version__ = '$GTAG'" > kintree/__init__.py 152 | env: 153 | REF: ${{ github.ref }} 154 | - name: Display the inferred version 155 | run: | 156 | head pyproject.toml 157 | head kintree/__init__.py 158 | - name: Set up Python 3.10 159 | uses: actions/setup-python@v2 160 | with: 161 | python-version: '3.10' 162 | - name: Install dependencies 163 | run: pip install -U poetry 164 | - name: Install poetry dependencies 165 | run: poetry install --no-root --no-dev --no-interaction 166 | - name: Build the package 167 | run: poetry build --no-interaction 168 | - name: Set up TestPyPI repo in poetry 169 | run: poetry config repositories.test https://test.pypi.org/legacy/ 170 | - name: Publish to Test PyPI 171 | run: > 172 | poetry publish 173 | --repository "test" 174 | --username "__token__" 175 | --password "$TOKEN_TEST_PYPI" 176 | env: 177 | TOKEN_TEST_PYPI: ${{ secrets.TOKEN_TEST_PYPI }} 178 | - name: Publish to PyPI 179 | run: > 180 | poetry publish 181 | --username "__token__" 182 | --password "$TOKEN_PYPI" 183 | env: 184 | TOKEN_PYPI: ${{ secrets.TOKEN_PYPI }} 185 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build files 2 | dist/ 3 | build/ 4 | *.spec 5 | # Cache and backup files 6 | *__pycache__* 7 | *.bck 8 | # Test files 9 | kintree/tests/* 10 | .coverage 11 | htmlcov/ 12 | .vscode/launch.json 13 | -------------------------------------------------------------------------------- /images/doc/digikey_api_approval_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/images/doc/digikey_api_approval_request.png -------------------------------------------------------------------------------- /images/doc/digikey_api_approval_request2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/images/doc/digikey_api_approval_request2.png -------------------------------------------------------------------------------- /images/doc/kintree_v1_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/images/doc/kintree_v1_example.png -------------------------------------------------------------------------------- /images/doc/kintree_v1_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/images/doc/kintree_v1_preview.png -------------------------------------------------------------------------------- /images/doc/kintree_v1_search_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/images/doc/kintree_v1_search_example.png -------------------------------------------------------------------------------- /images/doc/kintree_v1_settings_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/images/doc/kintree_v1_settings_user.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/images/logo.png -------------------------------------------------------------------------------- /images/python_versions.svg: -------------------------------------------------------------------------------- 1 | pythonpython3.9 | 3.10 | 3.11 | 3.123.9 | 3.10 | 3.11 | 3.12 -------------------------------------------------------------------------------- /invoke.yaml: -------------------------------------------------------------------------------- 1 | debug: true 2 | run: 3 | echo: false -------------------------------------------------------------------------------- /kintree/__init__.py: -------------------------------------------------------------------------------- 1 | # WARNING: This file is overwriten when publishing to PyPI 2 | # __version__ refers to the tag version instead 3 | 4 | # VERSION INFORMATION 5 | version_info = { 6 | 'MAJOR_REVISION': 1, 7 | 'MINOR_REVISION': 1, 8 | 'RELEASE_STATUS': '99dev', 9 | } 10 | 11 | __version__ = '.'.join([str(v) for v in version_info.values()]) 12 | -------------------------------------------------------------------------------- /kintree/common/part_tools.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from ..config import settings 4 | from ..config import config_interface 5 | from .tools import cprint 6 | 7 | 8 | def generate_part_number(category: str, part_pk: int, category_code='') -> str: 9 | ''' Generate Internal Part Number (IPN) ''' 10 | ipn_elements = [] 11 | 12 | # Prefix 13 | if settings.CONFIG_IPN.get('IPN_ENABLE_PREFIX', False): 14 | ipn_elements.append(settings.CONFIG_IPN.get('IPN_PREFIX', '')) 15 | 16 | # Category code 17 | if settings.CONFIG_IPN.get('IPN_CATEGORY_CODE', False): 18 | if not category_code: 19 | CATEGORY_CODES = config_interface.load_file(settings.CONFIG_CATEGORIES)['CODES'] 20 | try: 21 | category_code = CATEGORY_CODES.get(category, '') 22 | except AttributeError: 23 | category_code = None 24 | if category_code: 25 | ipn_elements.append(category_code) 26 | 27 | # Unique ID (mandatory) 28 | try: 29 | unique_id = str(part_pk).zfill(int(settings.CONFIG_IPN.get('IPN_UNIQUE_ID_LENGTH', '6'))) 30 | except: 31 | return None 32 | ipn_elements.append(unique_id) 33 | 34 | # Suffix 35 | if settings.CONFIG_IPN.get('IPN_ENABLE_SUFFIX', False): 36 | ipn_elements.append(settings.CONFIG_IPN.get('IPN_SUFFIX', '')) 37 | 38 | # Build IPN 39 | ipn = '-'.join(ipn_elements) 40 | 41 | return ipn 42 | 43 | 44 | def compare(new_part_parameters: dict, db_part_parameters: dict, include_filters: list) -> bool: 45 | ''' Compare two InvenTree parts based on parameters (specs) ''' 46 | try: 47 | for parameter, value in new_part_parameters.items(): 48 | # Check for filters 49 | if include_filters: 50 | # Compare only parameters present in include_filters 51 | if parameter in include_filters and value != db_part_parameters[parameter]: 52 | return False 53 | else: 54 | # Compare all parameters 55 | if value != db_part_parameters[parameter]: 56 | return False 57 | except KeyError: 58 | cprint('[INFO]\tWarning: Failed to compare part with database', silent=settings.HIDE_DEBUG) 59 | return False 60 | 61 | return True 62 | 63 | 64 | def clean_parameter_value(category: str, name: str, value: str) -> str: 65 | ''' Clean-up parameter value for consumption in InvenTree and KiCad ''' 66 | category = category.lower() 67 | name = name.lower() 68 | 69 | # Parameter specific filters 70 | # Package 71 | if 'package' in name and 'size' not in name: 72 | space_split = value.split() 73 | 74 | # Return value before the space 75 | if len(space_split) > 1: 76 | value = space_split[0].replace(',', '') 77 | 78 | # Sizes 79 | if 'size' in name or \ 80 | 'height' in name or \ 81 | 'pitch' in name or \ 82 | 'outline' in name: 83 | # imperial = re.findall('[.0-9]*"', value) 84 | metric = re.findall('[.0-9]*mm', value) 85 | len_metric = len(metric) 86 | 87 | # Return only the metric dimensions 88 | if len_metric > 0 and len_metric <= 1: 89 | # One dimension 90 | if 'dia' in value.lower(): 91 | # Check if diameter value 92 | value = '⌀' + metric[0] 93 | else: 94 | value = metric[0] 95 | elif len_metric > 1 and len_metric <= 2: 96 | # Two dimensions 97 | value = metric[0].replace('mm', '') + 'x' + metric[1] 98 | elif len_metric > 2 and len_metric <= 3: 99 | # Three dimensions 100 | value = metric[0].replace('mm', '') + 'x' + metric[1].replace('mm', '') + 'x' + metric[2] 101 | 102 | # Power 103 | if 'power' in name: 104 | # decimal = re.findall('[0-9]\.[0-9]*W', value) 105 | ratio = re.findall('[0-9]/[0-9]*W', value) 106 | 107 | # Return ratio 108 | if len(ratio) > 0: 109 | value = ratio[0] 110 | 111 | # ESR, DCR, RDS 112 | if 'esr' in name or \ 113 | 'dcr' in name or \ 114 | 'rds' in name: 115 | value = value.replace('Max', '').replace(' ', '').replace('Ohm', 'R') 116 | 117 | # Category specific filters 118 | # RESISTORS 119 | if 'resistor' in category: 120 | if 'resistance' in name: 121 | space_split = value.split() 122 | 123 | if len(space_split) > 1: 124 | resistance = space_split[0] 125 | unit = space_split[1] 126 | 127 | unit_filter = ['kOhms', 'MOhms', 'GOhms'] 128 | if unit in unit_filter: 129 | unit = unit.replace('Ohms', '').upper() 130 | else: 131 | unit = unit.replace('Ohms', 'R') 132 | 133 | value = resistance + unit 134 | 135 | # General filters 136 | # Clean-up ranges 137 | separator = '~' 138 | if separator in value: 139 | space_split = value.split() 140 | first_value = space_split[0] 141 | if len(space_split) > 2: 142 | second_value = space_split[2] 143 | 144 | # Substract digits, negative sign, points from first value to get unit 145 | unit = first_value.replace(re.findall('[-.0-9]*', first_value)[0], '') 146 | 147 | if unit: 148 | value = first_value.replace(unit, '') + separator + second_value 149 | 150 | # Remove parenthesis section 151 | if '(' in value: 152 | parenthesis = re.findall(r'\(.*\)', value) 153 | 154 | if parenthesis: 155 | for item in parenthesis: 156 | value = value.replace(item, '') 157 | 158 | # Remove leftover spaces 159 | value = value.replace(' ', '') 160 | 161 | # Remove spaces (for specific cases) 162 | if '@' in value: 163 | value = value.replace(' ', '') 164 | 165 | # Escape double-quote (else causes library error in KiCad) 166 | if '"' in value: 167 | value = value.replace('"', '\\"') 168 | 169 | # cprint(value) 170 | return value 171 | -------------------------------------------------------------------------------- /kintree/common/progress.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | CREATE_PART_PROGRESS: float 4 | MAX_PROGRESS = 1.0 5 | DEFAULT_PROGRESS = 0.1 6 | 7 | 8 | def reset_progress_bar(progress_bar) -> bool: 9 | ''' Reset progress bar ''' 10 | global CREATE_PART_PROGRESS 11 | 12 | # Reset progress 13 | CREATE_PART_PROGRESS = 0 14 | progress_bar.color = None 15 | progress_bar.value = 0 16 | progress_bar.update() 17 | time.sleep(0.1) 18 | 19 | return True 20 | 21 | 22 | def progress_increment(inc): 23 | ''' Increment progress ''' 24 | global CREATE_PART_PROGRESS, MAX_PROGRESS 25 | 26 | if CREATE_PART_PROGRESS + inc < MAX_PROGRESS: 27 | CREATE_PART_PROGRESS += inc 28 | else: 29 | CREATE_PART_PROGRESS = MAX_PROGRESS 30 | 31 | return CREATE_PART_PROGRESS 32 | 33 | 34 | def update_progress_bar(progress_bar, increment=0) -> bool: 35 | ''' Update progress bar during part creation ''' 36 | global DEFAULT_PROGRESS 37 | 38 | if not progress_bar: 39 | return True 40 | 41 | if increment: 42 | inc = increment 43 | else: 44 | # Default 45 | inc = DEFAULT_PROGRESS 46 | 47 | current_value = progress_bar.value * 100 48 | new_value = progress_increment(inc) * 100 49 | # Smooth progress 50 | for i in range(int(new_value - current_value)): 51 | progress_bar.value += i / 100 52 | progress_bar.update() 53 | time.sleep(0.05) 54 | 55 | return True 56 | -------------------------------------------------------------------------------- /kintree/common/tools.py: -------------------------------------------------------------------------------- 1 | import builtins 2 | import json 3 | import os 4 | from shutil import copyfile 5 | 6 | 7 | # CUSTOM PRINT METHOD 8 | class pcolors: 9 | HEADER = '\033[95m' 10 | OKBLUE = '\033[94m' 11 | OKGREEN = '\033[92m' 12 | WARNING = '\033[93m' 13 | ERROR = '\033[91m' 14 | ENDC = '\033[0m' 15 | BOLD = '\033[1m' 16 | UNDERLINE = '\033[4m' 17 | 18 | # Overload print function with custom pretty-print 19 | 20 | 21 | def cprint(*args, **kwargs): 22 | # Check if silent is set 23 | try: 24 | silent = kwargs.pop('silent') 25 | except: 26 | silent = False 27 | if not silent: 28 | if type(args[0]) is dict: 29 | return builtins.print(json.dumps(*args, **kwargs, indent=4, sort_keys=True)) 30 | else: 31 | try: 32 | args = list(args) 33 | if 'warning' in args[0].lower(): 34 | args[0] = f'{pcolors.WARNING}{args[0]}{pcolors.ENDC}' 35 | elif 'error' in args[0].lower(): 36 | args[0] = f'{pcolors.ERROR}{args[0]}{pcolors.ENDC}' 37 | elif 'fail' in args[0].lower(): 38 | args[0] = f'{pcolors.ERROR}{args[0]}{pcolors.ENDC}' 39 | elif 'success' in args[0].lower(): 40 | args[0] = f'{pcolors.OKGREEN}{args[0]}{pcolors.ENDC}' 41 | elif 'pass' in args[0].lower(): 42 | args[0] = f'{pcolors.OKGREEN}{args[0]}{pcolors.ENDC}' 43 | elif 'main' in args[0].lower(): 44 | args[0] = f'{pcolors.HEADER}{args[0]}{pcolors.ENDC}' 45 | elif 'skipping' in args[0].lower(): 46 | args[0] = f'{pcolors.BOLD}{args[0]}{pcolors.ENDC}' 47 | args = tuple(args) 48 | except: 49 | pass 50 | return builtins.print(*args, **kwargs, flush=True) 51 | ### 52 | 53 | 54 | def create_library(library_path: str, symbol: str, template_lib: str): 55 | ''' Create library files if they don\'t exist ''' 56 | if not os.path.exists(library_path): 57 | os.mkdir(library_path) 58 | new_kicad_sym_file = os.path.join(library_path, f'{symbol}.kicad_sym') 59 | if not os.path.exists(new_kicad_sym_file): 60 | copyfile(template_lib, new_kicad_sym_file) 61 | 62 | 63 | def get_image_with_retries(url, headers, retries=3, wait=5, silent=False): 64 | """ Method to download image with cloudscraper library and retry attempts""" 65 | import cloudscraper 66 | import time 67 | scraper = cloudscraper.create_scraper() 68 | for attempt in range(retries): 69 | try: 70 | response = scraper.get(url, headers=headers, timeout=wait) 71 | if response.status_code == 200: 72 | return response 73 | else: 74 | cprint(f'[INFO]\tWarning: Image download Attempt {attempt + 1} failed with status code {response.status_code}. Retrying in {wait} seconds...', silent=silent) 75 | except Exception as e: 76 | cprint(f'[INFO]\tWarning: Image download Attempt {attempt + 1} encountered an error: {e}. Retrying in {wait} seconds...', silent=silent) 77 | time.sleep(wait) 78 | cprint('[INFO]\tWarning: All Image download attempts failed. Could not retrieve the image.', silent=silent) 79 | return None 80 | 81 | 82 | def download(url, filetype='API data', fileoutput='', timeout=3, enable_headers=False, requests_lib=False, try_cloudscraper=False, silent=False): 83 | ''' Standard method to download URL content, with option to save to local file (eg. images) ''' 84 | 85 | import socket 86 | import urllib.request 87 | import requests 88 | 89 | # A more detailed headers was needed for request to Jameco 90 | headers = { 91 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36', 92 | 'Accept': 'applicaiton/json,image/webp,image/apng,image/*,*/*;q=0.8', 93 | 'Accept-Encoding': 'Accept-Encoding: gzip, deflate, br', 94 | 'Accept-Language': 'en-US,en;q=0.9', 95 | 'Connection': 'keep-alive', 96 | 'Cache-Control': 'no-cache', 97 | } 98 | 99 | # Set default timeout for download socket 100 | socket.setdefaulttimeout(timeout) 101 | if enable_headers and not requests_lib: 102 | opener = urllib.request.build_opener() 103 | opener.addheaders = list(headers.items()) 104 | urllib.request.install_opener(opener) 105 | try: 106 | if filetype == 'PDF': 107 | # some distributors/manufacturers implement 108 | # redirects which don't allow direct downloads 109 | if 'gotoUrl' in url and 'www.ti.com' in url: 110 | mpn = url.split('%2F')[-1] 111 | url = f'https://www.ti.com/lit/ds/symlink/{mpn}.pdf' 112 | if filetype == 'Image' or filetype == 'PDF': 113 | # Enable use of requests library for downloading files (some URLs do NOT work with urllib) 114 | if requests_lib: 115 | response = requests.get(url, headers=headers, timeout=timeout, allow_redirects=True) 116 | if filetype.lower() not in response.headers['Content-Type'].lower(): 117 | cprint(f'[INFO]\tWarning: {filetype} download returned the wrong file type', silent=silent) 118 | return None 119 | with open(fileoutput, 'wb') as file: 120 | file.write(response.content) 121 | elif try_cloudscraper: 122 | response = get_image_with_retries(url, headers=headers) 123 | if filetype.lower() not in response.headers['Content-Type'].lower(): 124 | cprint(f'[INFO]\tWarning: {filetype} download returned the wrong file type', silent=silent) 125 | return None 126 | with open(fileoutput, 'wb') as file: 127 | file.write(response.content) 128 | else: 129 | (file, headers) = urllib.request.urlretrieve(url, filename=fileoutput) 130 | if filetype.lower() not in headers['Content-Type'].lower(): 131 | cprint(f'[INFO]\tWarning: {filetype} download returned the wrong file type', silent=silent) 132 | return None 133 | return file 134 | else: 135 | # some suppliers work with requests.get(), others need urllib.request.urlopen() 136 | try: 137 | response = requests.get(url) 138 | data_json = response.json() 139 | return data_json 140 | except requests.exceptions.JSONDecodeError: 141 | try: 142 | url_data = urllib.request.urlopen(url) 143 | data = url_data.read() 144 | data_json = json.loads(data.decode('utf-8')) 145 | return data_json 146 | finally: 147 | pass 148 | except (socket.timeout, requests.exceptions.ConnectTimeout, requests.exceptions.ReadTimeout): 149 | cprint(f'[INFO]\tWarning: {filetype} download socket timed out ({timeout}s)', silent=silent) 150 | except (urllib.error.HTTPError, requests.exceptions.ConnectionError): 151 | cprint(f'[INFO]\tWarning: {filetype} download failed (HTTP Error)', silent=silent) 152 | except (urllib.error.URLError, ValueError, AttributeError): 153 | cprint(f'[INFO]\tWarning: {filetype} download failed (URL Error)', silent=silent) 154 | except requests.exceptions.SSLError: 155 | cprint(f'[INFO]\tWarning: {filetype} download failed (SSL Error)', silent=silent) 156 | except FileNotFoundError: 157 | cprint(f'[INFO]\tWarning: {os.path.dirname(fileoutput)} folder does not exist', silent=silent) 158 | return None 159 | 160 | 161 | def download_with_retry(url: str, full_path: str, silent=False, **kwargs) -> str: 162 | ''' Standard method to download image URL to local file ''' 163 | 164 | if not url: 165 | cprint('[INFO]\tError: Missing image URL', silent=silent) 166 | return False 167 | 168 | # Try without headers 169 | file = download(url, fileoutput=full_path, silent=silent, **kwargs) 170 | 171 | if not file: 172 | # Try with headers 173 | file = download(url, fileoutput=full_path, enable_headers=True, silent=silent, **kwargs) 174 | 175 | if not file: 176 | # Try with requests library 177 | file = download(url, fileoutput=full_path, enable_headers=True, requests_lib=True, silent=silent, **kwargs) 178 | 179 | if not file: 180 | # Try with cloudscraper 181 | file = download(url, fileoutput=full_path, enable_headers=True, requests_lib=False, try_cloudscraper=True, silent=silent, **kwargs) 182 | 183 | # Still nothing 184 | if not file: 185 | return False 186 | 187 | cprint(f'[INFO]\tDownload success ({url=})', silent=silent) 188 | return True 189 | -------------------------------------------------------------------------------- /kintree/config/automationdirect/automationdirect_api.yaml: -------------------------------------------------------------------------------- 1 | AUTOMATIONDIRECT_API_ROOT_URL: "https://www.automationdirect.com" 2 | AUTOMATIONDIRECT_API_URL: "https://www.automationdirect.com/ajax?&fctype=adc.falcon.search.SearchFormCtrl&cmd=AjaxSearch" 3 | AUTOMATIONDIRECT_API_SEARCH_QUERY: "&searchquery=" # can be anything but probably best to set to search term 4 | AUTOMATIONDIRECT_API_SEARCH_STRING: "&solrQueryString=q%3D" # append search term to this and combine with other params 5 | AUTOMATIONDIRECT_API_IMAGE_PATH: "https://cdn.automationdirect.com/images/products/medium/m_" # image path for medium size image on product page -------------------------------------------------------------------------------- /kintree/config/automationdirect/automationdirect_config.yaml: -------------------------------------------------------------------------------- 1 | SUPPLIER_DATABASE_NAME: Automation Direct 2 | SEARCH_NAME: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_REVISION: null 5 | SEARCH_KEYWORDS: null 6 | SEARCH_SKU: null 7 | SEARCH_MANUFACTURER: null 8 | SEARCH_MPN: null 9 | SEARCH_SUPPLIER_URL: null 10 | SEARCH_DATASHEET: null 11 | EXTRA_FIELDS: null -------------------------------------------------------------------------------- /kintree/config/digikey/digikey_api.yaml: -------------------------------------------------------------------------------- 1 | DIGIKEY_CLIENT_ID: '' 2 | DIGIKEY_CLIENT_SECRET: '' -------------------------------------------------------------------------------- /kintree/config/digikey/digikey_categories.yaml: -------------------------------------------------------------------------------- 1 | Capacitors: 2 | Aluminium: 3 | - Aluminum Electrolytic Capacitors 4 | Ceramic: 5 | - Ceramic Capacitors 6 | - Ceramic 7 | Polymer: 8 | - Aluminum - Polymer Capacitors 9 | - Tantalum - Polymer Capacitors 10 | Super Capacitors: 11 | - Electric Double Layer Capacitors (EDLC), Supercapacitors 12 | Tantalum: 13 | - Tantalum Capacitors 14 | Circuit Protections: 15 | Fuses: 16 | - Fuses 17 | PTC: 18 | - PTC Resettable Fuses 19 | TVS: 20 | - TVS - Diodes 21 | Connectors: 22 | Board-to-Board: 23 | - Rectangular Connectors - Arrays, Edge Type, Mezzanine (Board to Board) 24 | - Rectangular Connectors - Spring Loaded 25 | Coaxial: 26 | - Coaxial Connectors (RF) 27 | FPC: 28 | - FFC, FPC (Flat Flexible) Connectors 29 | Header: 30 | - Rectangular Connectors - Headers, Male Pins 31 | - Rectangular Connectors - Headers, Receptacles, Female Sockets 32 | Interface: 33 | - USB, DVI, HDMI Connectors 34 | - Barrel - Audio Connectors 35 | - Memory Connectors - PC Card Sockets 36 | - Modular Connectors - Jacks With Magnetics 37 | Crystals and Oscillators: 38 | Crystals: 39 | - Crystals 40 | Oscillators: 41 | - Oscillators 42 | Diodes: 43 | LED: 44 | - LED Indication - Discrete 45 | - Addressable, Specialty 46 | Zener: 47 | - Diodes - Zener - Single 48 | __Schottky: 49 | - Diodes - Rectifiers - Single 50 | __Standard: 51 | - Diodes - Rectifiers - Single 52 | Inductors: 53 | Ferrite Bead: 54 | - Ferrite Beads and Chips 55 | Power: 56 | - Fixed Inductors 57 | Integrated Circuits: 58 | Interface: 59 | - Interface - CODECs 60 | - PMIC - Battery Chargers 61 | - Interface - Analog Switches, Multiplexers, Demultiplexers 62 | - Interface - Controllers 63 | Logic: 64 | - Logic - Translators, Level Shifters 65 | - Clock/Timing - Clock Generators, PLLs, Frequency Synthesizers 66 | - Logic - Buffers, Drivers, Receivers, Transceivers 67 | Microcontroller: 68 | - Embedded - Microcontrollers 69 | Memory: 70 | - Memory 71 | Sensor: 72 | - Humidity, Moisture Sensors 73 | - Motion Sensors - IMUs (Inertial Measurement Units) 74 | - PMIC - Current Regulation/Management 75 | Mechanicals: 76 | Standoff: 77 | - Board Spacers, Standoffs 78 | Switch: 79 | - Tactile Switches 80 | - Slide Switches 81 | Power Management: 82 | LDO: 83 | - PMIC - Voltage Regulators - Linear 84 | __Boost: 85 | - PMIC - Voltage Regulators - DC DC Switching Regulators 86 | __Buck: 87 | - PMIC - Voltage Regulators - DC DC Switching Regulators 88 | RF: 89 | Antenna: null 90 | Chipset: null 91 | Filter: 92 | - Balun 93 | Resistors: 94 | Potentiometers: 95 | - Potentiometers, Variable Resistors 96 | - Rotary Potentiometers, Rheostats 97 | Surface Mount: 98 | - Chip Resistor - Surface Mount 99 | Through Hole: 100 | - Through Hole Resistors 101 | Transistors: 102 | __N-Channel FET: 103 | - Transistors - FETs, MOSFETs - Single 104 | __NPN: 105 | - Transistors - Bipolar (BJT) - Single 106 | - Transistors - FETs, MOSFETs - Single 107 | __P-Channel FET: 108 | - Transistors - FETs, MOSFETs - Single 109 | __PNP: 110 | - Transistors - Bipolar (BJT) - Single 111 | Load Switches: 112 | - PMIC - Power Distribution Switches, Load Drivers 113 | -------------------------------------------------------------------------------- /kintree/config/digikey/digikey_config.yaml: -------------------------------------------------------------------------------- 1 | SUPPLIER_INVENTREE_NAME: Digi-Key 2 | SEARCH_NAME: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_REVISION: null 5 | SEARCH_KEYWORDS: null 6 | SEARCH_SKU: null 7 | SEARCH_MANUFACTURER: null 8 | SEARCH_MPN: null 9 | SEARCH_SUPPLIER_URL: null 10 | SEARCH_DATASHEET: null 11 | EXTRA_FIELDS: null -------------------------------------------------------------------------------- /kintree/config/element14/element14_api.yaml: -------------------------------------------------------------------------------- 1 | ELEMENT14_PRODUCT_SEARCH_API_KEY: null 2 | FARNELL_STORE: null 3 | NEWARK_STORE: null 4 | ELEMENT14_STORE: null -------------------------------------------------------------------------------- /kintree/config/element14/element14_config.yaml: -------------------------------------------------------------------------------- 1 | SUPPLIER_INVENTREE_NAME: null 2 | SEARCH_NAME: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_REVISION: null 5 | SEARCH_KEYWORDS: null 6 | SEARCH_SKU: null 7 | SEARCH_MANUFACTURER: null 8 | SEARCH_MPN: null 9 | SEARCH_SUPPLIER_URL: null 10 | SEARCH_DATASHEET: null 11 | EXTRA_FIELDS: null -------------------------------------------------------------------------------- /kintree/config/inventree/categories.yaml: -------------------------------------------------------------------------------- 1 | CATEGORIES: 2 | Assemblies: 3 | Printed-Circuit Board Assembly: null 4 | Product: null 5 | Capacitors: 6 | Aluminium: null 7 | Ceramic: 8 | '0402': null 9 | '0603': null 10 | '0805': null 11 | Polymer: null 12 | Super Capacitors: null 13 | Tantalum: null 14 | Circuit Protections: 15 | Fuses: null 16 | PTC: null 17 | TVS: null 18 | Connectors: 19 | Battery: null 20 | Board-to-Board: null 21 | Coaxial: null 22 | FPC: null 23 | Header: null 24 | Interface: null 25 | Crystals and Oscillators: 26 | Crystals: null 27 | Oscillators: null 28 | Diodes: 29 | LED: null 30 | Schottky: null 31 | Standard: null 32 | Zener: null 33 | Inductors: 34 | Ferrite Bead: null 35 | Power: null 36 | Integrated Circuits: 37 | Interface: null 38 | Logic: null 39 | Memory: null 40 | Microcontroller: null 41 | Sensor: null 42 | Mechanicals: 43 | Nuts: null 44 | Screws: null 45 | Standoff: null 46 | Switch: null 47 | Miscellaneous: 48 | Batteries: null 49 | Modules: null 50 | Power Management: 51 | Boost: null 52 | Buck: null 53 | LDO: null 54 | PMIC: null 55 | Printed-Circuit Boards: null 56 | RF: 57 | Antenna: null 58 | Chipset: null 59 | Filter: null 60 | Shield: null 61 | Resistors: 62 | NTC: null 63 | Potentiometers: null 64 | Surface Mount: null 65 | Through Hole: null 66 | Transistors: 67 | Load Switches: null 68 | N-Channel FET: null 69 | NPN: null 70 | P-Channel FET: null 71 | PNP: null 72 | CODES: 73 | Assemblies: PCA 74 | Capacitors: CAP 75 | Circuit Protections: PRO 76 | Connectors: CON 77 | Crystals and Oscillators: CLK 78 | Diodes: DIO 79 | Inductors: IND 80 | Integrated Circuits: ICS 81 | Mechanicals: MEC 82 | Miscellaneous: MIS 83 | Modules: MOD 84 | Power Management: PWR 85 | Printed-Circuit Boards: PCB 86 | RF: RFC 87 | Resistors: RES 88 | Transistors: TRA -------------------------------------------------------------------------------- /kintree/config/inventree/inventree_dev.yaml: -------------------------------------------------------------------------------- 1 | ENABLE: true 2 | ENABLE_PROXY: false 3 | PASSWORD: !!binary | 4 | '' 5 | PROXIES: null 6 | SERVER_ADDRESS: '' 7 | USERNAME: '' 8 | DATASHEET_UPLOAD: false -------------------------------------------------------------------------------- /kintree/config/inventree/inventree_prod.yaml: -------------------------------------------------------------------------------- 1 | ENABLE: true 2 | ENABLE_PROXY: false 3 | PASSWORD: !!binary | 4 | '' 5 | PROXIES: null 6 | SERVER_ADDRESS: '' 7 | USERNAME: '' 8 | DATASHEET_UPLOAD: false -------------------------------------------------------------------------------- /kintree/config/inventree/parameters.yaml: -------------------------------------------------------------------------------- 1 | # Parameters 2 | # Name: Unit 3 | Min Output Voltage: V 4 | Antenna Type: null 5 | B Constant: K 6 | Breakdown Voltage: V 7 | Capacitance: nF 8 | Clamping Voltage: V 9 | Collector Gate Voltage: V 10 | DC Resistance: "m\u03A9" 11 | ESR: "m\u03A9" 12 | Footprint: null 13 | Forward Voltage: V 14 | Frequency: Hz 15 | Frequency Stability: ppm 16 | Frequency Tolerance: ppm 17 | Function Type: null 18 | Interface Type: null 19 | LED Color: null 20 | Load Capacitance: pF 21 | Locking: null 22 | Mating Height: mm 23 | Max Input Voltage: V 24 | Max Output Voltage: V 25 | Maximum Gate Voltage: V 26 | Memory Size: null 27 | Min Input Voltage: V 28 | Mounting Type: null 29 | Number of Channels: null 30 | Number of Contacts: null 31 | Number of Elements: null 32 | Number of Rows: null 33 | Orientation: null 34 | Output Current: A 35 | Output Type: null 36 | Package Height: mm 37 | Package Size: mm 38 | Package Type: null 39 | Pitch: mm 40 | Polarity: null 41 | Quiescent Current: A 42 | RDS On Resistance: "\u03A9" 43 | RDS On Voltage: V 44 | Rated Current: A 45 | Rated Power: W 46 | Rated Voltage: V 47 | Saturation Current: A 48 | Shielding: null 49 | Standoff Voltage: V 50 | Symbol: null 51 | Temperature Grade: null 52 | Temperature Range: "\xB0C" 53 | Tolerance: '%' 54 | Value: null 55 | -------------------------------------------------------------------------------- /kintree/config/inventree/parameters_filters.yaml: -------------------------------------------------------------------------------- 1 | Capacitors: 2 | - Value 3 | - Rated Voltage 4 | - Tolerance 5 | - Package Type 6 | - Temperature Grade 7 | Circuit Protections: 8 | - Value 9 | Connectors: 10 | - Value 11 | Crystals and Oscillators: 12 | - Value 13 | - Package Type 14 | - Package Size 15 | - Temperature Range 16 | Diodes: 17 | - Value 18 | Inductors: 19 | - Value 20 | - Rated Current 21 | - Package Type 22 | - Package Size 23 | - Temperature Range 24 | Integrated Circuits: 25 | - Value 26 | Mechanicals: 27 | - Value 28 | Modules: 29 | - null 30 | Power Management: 31 | - Value 32 | Printed-Circuit Boards: 33 | - null 34 | RF: 35 | - Value 36 | Resistors: 37 | - Value 38 | - Tolerance 39 | - Rated Power 40 | - Package Type 41 | - Temperature Range 42 | Transistors: 43 | - Value 44 | -------------------------------------------------------------------------------- /kintree/config/inventree/stock_locations.yaml: -------------------------------------------------------------------------------- 1 | STOCK_LOCATIONS: null -------------------------------------------------------------------------------- /kintree/config/inventree/supplier_parameters.yaml: -------------------------------------------------------------------------------- 1 | # Parameter Mapping between InvenTree parameter template and suppliers parameters naming 2 | # Each template parameter can match to multiple suppliers parameters 3 | # Categories (main keys) should match categories in the categories.yaml file 4 | # Parameter template names should match those found in the parameters.yaml file 5 | Base: 6 | Temperature Range: 7 | - Operating Temperature 8 | Package Type: 9 | - Package / Case 10 | Passives: 11 | Tolerance: 12 | - Tolerance 13 | Capacitors: 14 | parent: 15 | - Base 16 | - Passives 17 | ESR: 18 | - ESR (Equivalent Series Resistance) 19 | Package Height: 20 | - Height - Seated (Max) 21 | - Thickness (Max) 22 | Package Size: 23 | - Size / Dimension 24 | Rated Voltage: 25 | - Voltage - Rated 26 | - Voltage Rated 27 | Temperature Grade: 28 | - Temperature Coefficient 29 | Temperature Range: 30 | - Operating Temperature 31 | Value: 32 | - Capacitance 33 | Circuit Protections: 34 | parent: 35 | - Base 36 | Breakdown Voltage: 37 | - Voltage - Breakdown (Min) 38 | Capacitance: 39 | - Capacitance @ Frequency 40 | Clamping Voltage: 41 | - Voltage - Clamping (Max) @ Ipp 42 | Rated Current: 43 | - Current Rating (Amps) 44 | - Current - Max 45 | Rated Power: 46 | - Power - Peak Pulse 47 | Rated Voltage: 48 | - Voltage Rating - DC 49 | - Voltage - Max 50 | Standoff Voltage: 51 | - Voltage - Reverse Standoff (Typ) 52 | Value: 53 | - Manufacturer Part Number 54 | Connectors: 55 | Frequency: 56 | - Frequency - Max 57 | Interface Type: 58 | - Connector Type 59 | - Flat Flex Type 60 | Locking: 61 | - Locking Feature 62 | - Fastening Type 63 | Mating Height: 64 | - Mated Stacking Heights 65 | Mounting Type: 66 | - Mounting Type 67 | Number of Contacts: 68 | - Number of Contacts 69 | - Number of Positions 70 | Number of Rows: 71 | - Number of Rows 72 | Orientation: 73 | - Orientation 74 | Package Height: 75 | - Height Above Board 76 | - Insulation Height 77 | Pitch: 78 | - Pitch 79 | - Pitch - Mating 80 | Polarity: 81 | - Gender 82 | Shielding: 83 | - Shielding 84 | Temperature Range: 85 | - Operating Temperature 86 | Value: 87 | - Manufacturer Part Number 88 | Crystals and Oscillators: 89 | parent: 90 | - Base 91 | Frequency Stability: 92 | - Frequency Stability 93 | Frequency Tolerance: 94 | - Frequency Tolerance 95 | Load Capacitance: 96 | - Load Capacitance 97 | Package Height: 98 | - Height - Seated (Max) 99 | Package Size: 100 | - Size / Dimension 101 | Rated Current: 102 | - Current - Supply (Max) 103 | Rated Voltage: 104 | - Voltage - Supply 105 | Value: 106 | - Frequency 107 | Diodes: 108 | parent: 109 | - Base 110 | Forward Voltage: 111 | - Voltage - Forward (Vf) (Max) @ If 112 | - Voltage - Forward (Vf) (Typ) 113 | Function Type: 114 | - Diode Type 115 | LED Color: 116 | - Color 117 | Rated Current: 118 | - Current - Average Rectified (Io) 119 | Rated Power: 120 | - Power - Max 121 | Rated Voltage: 122 | - Voltage - DC Reverse (Vr) (Max) 123 | - Voltage - Zener (Nom) (Vz) 124 | Temperature Range: 125 | - Operating Temperature - Junction 126 | Value: 127 | - Manufacturer Part Number 128 | Inductors: 129 | parent: 130 | - Base 131 | - Passives 132 | ESR: 133 | - DC Resistance (DCR) 134 | - DC Resistance (DCR) (Max) 135 | Package Height: 136 | - Height - Seated (Max) 137 | - Height (Max) 138 | Package Size: 139 | - Size / Dimension 140 | Rated Current: 141 | - Current Rating (Max) 142 | - Current Rating (Amps) 143 | Saturation Current: 144 | - Current - Saturation 145 | Shielding: 146 | - Shielding 147 | Value: 148 | - Inductance 149 | - Impedance @ Frequency 150 | Integrated Circuits: 151 | parent: 152 | - Base 153 | Frequency: 154 | - Clock Frequency 155 | - Speed 156 | - Data Rate 157 | - Frequency Range 158 | - -3db Bandwidth 159 | Function Type: 160 | - Translator Type 161 | - Technology 162 | - Core Processor 163 | - Type 164 | - Sensor Type 165 | Memory Size: 166 | - Program Memory Size 167 | - Memory Size 168 | Number of Channels: 169 | - Channels per Circuit 170 | Rated Voltage: 171 | - Voltage - VCCA 172 | - Voltage - VCCB 173 | - Voltage - Supply 174 | - Voltage - Supply (Vcc/Vdd) 175 | - Voltage - Supply, Digital 176 | - Voltage - Supply, Single (V+) 177 | Value: 178 | - Manufacturer Part Number 179 | Mechanicals: 180 | parent: 181 | - Base 182 | Function Type: 183 | - Circuit 184 | - Type 185 | Mounting Type: 186 | - Mounting Type 187 | - Features 188 | Package Height: 189 | - Between Board Height 190 | Package Size: 191 | - Outline 192 | - Diameter - Outside 193 | Package Type: 194 | - Screw, Thread Size 195 | Rated Current: 196 | - Contact Rating @ Voltage 197 | Value: 198 | - Manufacturer Part Number 199 | Power Management: 200 | parent: 201 | - Base 202 | Min Output Voltage: 203 | - Voltage - Output (Min/Fixed) 204 | Frequency: 205 | - Frequency - Switching 206 | Function Type: 207 | - Topology 208 | Max Input Voltage: 209 | - Voltage - Input (Max) 210 | Max Output Voltage: 211 | - Voltage - Output (Max) 212 | Min Input Voltage: 213 | - Voltage - Input (Min) 214 | Output Type: 215 | - Output Type 216 | Package Type: 217 | - Supplier Device Package 218 | Quiescent Current: 219 | - Current - Quiescent (Iq) 220 | Rated Current: 221 | - Current - Output 222 | Value: 223 | - Manufacturer Part Number 224 | RF: 225 | parent: 226 | - Base 227 | Frequency: 228 | - Frequency Range 229 | Function Type: null 230 | Rated Voltage: null 231 | Value: 232 | - Manufacturer Part Number 233 | Resistors: 234 | parent: 235 | - Passives 236 | Package Type: 237 | - Supplier Device Package 238 | Rated Power: 239 | - Power (Watts) 240 | Temperature Range: 241 | - Operating Temperature 242 | Value: 243 | - Resistance 244 | Transistors: 245 | Collector-Gate Voltage: 246 | - Vce Saturation (Max) @ Ib, Ic 247 | - Vgs(th) (Max) @ Id 248 | Function Type: 249 | - Transistor Type 250 | - FET Type 251 | Maximum Gate Voltage: 252 | - Vgs (Max) 253 | Package Type: 254 | - Supplier Device Package 255 | RDS On Resistance: 256 | - Rds On (Max) @ Id, Vgs 257 | Rated Current: 258 | - Current - Collector (Ic) (Max) 259 | - "Current - Continuous Drain (Id) @ 25\xB0C" 260 | Rated Power: 261 | - Power - Max 262 | - Power Dissipation (Max) 263 | Rated Voltage: 264 | - Voltage - Collector Emitter Breakdown (Max) 265 | - Drain to Source Voltage (Vdss) 266 | Temperature Range: 267 | - Operating Temperature 268 | Value: 269 | - Manufacturer Part Number 270 | -------------------------------------------------------------------------------- /kintree/config/inventree/suppliers.yaml: -------------------------------------------------------------------------------- 1 | Digi-Key: 2 | enable: true 3 | name: Digi-Key 4 | Mouser: 5 | enable: true 6 | name: Mouser 7 | Element14: 8 | enable: true 9 | name: Element14 10 | Farnell: 11 | enable: true 12 | name: Farnell 13 | Jameco: 14 | enable: true 15 | name: Jameco 16 | AutomationDirect: 17 | enable: true 18 | name: Automation Direct 19 | Newark: 20 | enable: true 21 | name: Newark 22 | LCSC: 23 | enable: true 24 | name: LCSC 25 | TME: 26 | enable: true 27 | name: TME -------------------------------------------------------------------------------- /kintree/config/jameco/jameco_api.yaml: -------------------------------------------------------------------------------- 1 | JAMECO_API_URL: https://ahzbkf.a.searchspring.io/api/search/search.json?ajaxCatalog=v3&resultsFormat=native&siteId=ahzbkf&q= -------------------------------------------------------------------------------- /kintree/config/jameco/jameco_config.yaml: -------------------------------------------------------------------------------- 1 | SUPPLIER_INVENTREE_NAME: Jameco Electronics 2 | SEARCH_NAME: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_REVISION: null 5 | SEARCH_KEYWORDS: null 6 | SEARCH_SKU: null 7 | SEARCH_MANUFACTURER: null 8 | SEARCH_MPN: null 9 | SEARCH_SUPPLIER_URL: null 10 | SEARCH_DATASHEET: null 11 | EXTRA_FIELDS: null -------------------------------------------------------------------------------- /kintree/config/kicad/kicad.yaml: -------------------------------------------------------------------------------- 1 | KICAD_SYMBOLS_PATH: '' 2 | KICAD_TEMPLATES_PATH: kintree/kicad/templates/ 3 | KICAD_FOOTPRINTS_PATH: '' -------------------------------------------------------------------------------- /kintree/config/kicad/kicad_map.yaml: -------------------------------------------------------------------------------- 1 | KICAD_FOOTPRINTS: 2 | KICAD_LIBRARIES: 3 | KICAD_TEMPLATES: 4 | Capacitors: 5 | Aluminium: capacitor-polarized 6 | Ceramic: capacitor 7 | Default: capacitor 8 | Polymer: capacitor-polarized 9 | Super Capacitors: capacitor-polarized 10 | Tantalum: capacitor-polarized 11 | Circuit Protections: 12 | Default: protection-unidir 13 | Fuse: fuse 14 | TVS: protection-unidir 15 | Connectors: 16 | Default: connector 17 | Crystals and Oscillators: 18 | Crystal 2P: crystal-2p 19 | Default: crystal-2p 20 | Oscillator 4P: oscillator-4p 21 | Diodes: 22 | Default: diode-standard 23 | LED: diode-led 24 | Schottky: diode-schottky 25 | Standard: diode-standard 26 | Zener: diode-zener 27 | Inductors: 28 | Default: inductor 29 | Ferrite Bead: ferrite-bead 30 | Power: inductor 31 | Integrated Circuits: 32 | Default: integrated-circuit 33 | Mechanicals: 34 | Default: default 35 | Power Management: 36 | Default: integrated-circuit 37 | Resistors: 38 | Default: resistor 39 | Surface Mount: resistor-sm 40 | Through Hole: resistor 41 | RF: 42 | Default: integrated-circuit 43 | Transistors: 44 | Default: transistor-nfet 45 | N-Channel FET: transistor-nfet 46 | NPN: transistor-npn 47 | P-Channel FET: transistor-pfet 48 | PNP: transistor-pnp 49 | -------------------------------------------------------------------------------- /kintree/config/lcsc/lcsc_api.yaml: -------------------------------------------------------------------------------- 1 | LCSC_API_URL: https://wmsc.lcsc.com/ftps/wm/product/detail?productCode= 2 | -------------------------------------------------------------------------------- /kintree/config/lcsc/lcsc_config.yaml: -------------------------------------------------------------------------------- 1 | SUPPLIER_INVENTREE_NAME: LCSC Electronics 2 | SEARCH_NAME: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_REVISION: null 5 | SEARCH_KEYWORDS: null 6 | SEARCH_SKU: null 7 | SEARCH_MANUFACTURER: null 8 | SEARCH_MPN: null 9 | SEARCH_SUPPLIER_URL: null 10 | SEARCH_DATASHEET: null 11 | EXTRA_FIELDS: null -------------------------------------------------------------------------------- /kintree/config/mouser/mouser_api.yaml: -------------------------------------------------------------------------------- 1 | MOUSER_PART_API_KEY: null -------------------------------------------------------------------------------- /kintree/config/mouser/mouser_config.yaml: -------------------------------------------------------------------------------- 1 | SUPPLIER_INVENTREE_NAME: Mouser Electronics 2 | SEARCH_NAME: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_REVISION: null 5 | SEARCH_KEYWORDS: null 6 | SEARCH_SKU: null 7 | SEARCH_MANUFACTURER: null 8 | SEARCH_MPN: null 9 | SEARCH_SUPPLIER_URL: null 10 | SEARCH_DATASHEET: null 11 | EXTRA_FIELDS: null -------------------------------------------------------------------------------- /kintree/config/tme/tme_api.yaml: -------------------------------------------------------------------------------- 1 | TME_API_TOKEN: NULL 2 | TME_API_SECRET: NULL 3 | TME_API_COUNTRY: US 4 | TME_API_LANGUAGE: EN -------------------------------------------------------------------------------- /kintree/config/tme/tme_config.yaml: -------------------------------------------------------------------------------- 1 | SUPPLIER_INVENTREE_NAME: TME 2 | SEARCH_NAME: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_REVISION: null 5 | SEARCH_KEYWORDS: null 6 | SEARCH_SKU: null 7 | SEARCH_MANUFACTURER: null 8 | SEARCH_MPN: null 9 | SEARCH_SUPPLIER_URL: null 10 | SEARCH_DATASHEET: null -------------------------------------------------------------------------------- /kintree/config/user/general.yaml: -------------------------------------------------------------------------------- 1 | DATASHEET_SAVE_ENABLED: false 2 | DATASHEET_SAVE_PATH: null 3 | DATASHEET_INVENTREE_ENABLED: false 4 | AUTOMATIC_BROWSER_OPEN: true 5 | INVENTREE_ENV: null 6 | DEFAULT_SUPPLIER: Digi-Key 7 | ENABLE_KICAD: false 8 | ENABLE_INVENTREE: false 9 | ENABLE_ALTERNATE: false 10 | CHECK_EXISTING: true -------------------------------------------------------------------------------- /kintree/config/user/internal_part_number.yaml: -------------------------------------------------------------------------------- 1 | IPN_ENABLE_CREATE: true 2 | IPN_USE_MANUFACTURER_PART_NUMBER: false 3 | IPN_PREFIX: null 4 | IPN_CATEGORY_CODE: true 5 | IPN_UNIQUE_ID_LENGTH: '6' 6 | IPN_ENABLE_PREFIX: false 7 | IPN_ENABLE_SUFFIX: true 8 | IPN_SUFFIX: '00' 9 | INVENTREE_DEFAULT_REV: 'A' -------------------------------------------------------------------------------- /kintree/config/user/search_api.yaml: -------------------------------------------------------------------------------- 1 | CATEGORY_MATCH_RATIO_LIMIT: 100 2 | CACHE_ENABLED: true 3 | CACHE_VALID_DAYS: '7' -------------------------------------------------------------------------------- /kintree/gui/gui.py: -------------------------------------------------------------------------------- 1 | import os 2 | import flet as ft 3 | 4 | from ..config import settings 5 | 6 | from .views.common import update_theme, handle_transition 7 | from .views.main import ( 8 | PartSearchView, 9 | InventreeView, 10 | KicadView, 11 | CreateView, 12 | ) 13 | from .views.settings import ( 14 | UserSettingsView, 15 | SupplierSettingsView, 16 | InvenTreeSettingsView, 17 | KiCadSettingsView, 18 | ) 19 | 20 | 21 | def init_gui(page: ft.Page): 22 | '''Initialize page''' 23 | # Alignments 24 | page.horizontal_alignment = ft.CrossAxisAlignment.CENTER 25 | page.vertical_alignment = ft.MainAxisAlignment.CENTER 26 | page.scroll = ft.ScrollMode.ALWAYS 27 | 28 | # Window Icon 29 | page.window.icon = os.path.join(settings.PROJECT_DIR, 'gui', 'logo.ico') 30 | page.window.title_bar_hidden = True 31 | 32 | # Theme 33 | update_theme(page) 34 | 35 | # Creating a progress bar that will be used 36 | # to show the user that the app is busy doing something 37 | page.splash = ft.ProgressBar(visible=False) 38 | 39 | # Update 40 | page.update() 41 | 42 | 43 | def kintree_gui(page: ft.Page): 44 | '''Ki-nTree GUI''' 45 | # Init 46 | init_gui(page) 47 | # Create main views 48 | part_view = PartSearchView(page) 49 | inventree_view = InventreeView(page) 50 | kicad_view = KicadView(page) 51 | create_view = CreateView(page) 52 | # Create settings views 53 | user_settings_view = UserSettingsView(page) 54 | supplier_settings_view = SupplierSettingsView(page) 55 | inventree_settings_view = InvenTreeSettingsView(page) 56 | kicad_settings_view = KiCadSettingsView(page) 57 | 58 | # Routing 59 | def route_change(route): 60 | # print(f'\n--> Routing to {route.route}') 61 | if '/main' in page.route or page.route == '/': 62 | page.views.clear() 63 | if 'part' in page.route or page.route == '/': 64 | page.views.append(part_view) 65 | if 'inventree' in page.route: 66 | page.views.append(inventree_view) 67 | elif 'kicad' in page.route: 68 | page.views.append(kicad_view) 69 | elif 'create' in page.route: 70 | page.views.append(create_view) 71 | elif '/settings' in page.route: 72 | if '/settings' in page.views[-1].route: 73 | page.views.pop() 74 | if 'user' in page.route: 75 | page.views.append(user_settings_view) 76 | elif 'supplier' in page.route: 77 | page.views.append(supplier_settings_view) 78 | elif 'inventree' in page.route: 79 | page.views.append(inventree_settings_view) 80 | elif 'kicad' in page.route: 81 | page.views.append(kicad_settings_view) 82 | else: 83 | page.views.append(user_settings_view) 84 | page.update() 85 | 86 | def view_pop(view): 87 | '''Pop setting view''' 88 | page.views.pop() 89 | top_view = page.views[-1] 90 | if 'main' in top_view.route: 91 | handle_transition(page, transition=True) 92 | # Route and render 93 | page.go(top_view.route) 94 | if 'main' in top_view.route: 95 | handle_transition( 96 | page, 97 | transition=False, 98 | update_page=True, 99 | timeout=0.3, 100 | ) 101 | if '/main/part' in top_view.route or '/main/inventree' in top_view.route: 102 | top_view.partial_update() 103 | 104 | page.on_route_change = route_change 105 | page.on_view_pop = view_pop 106 | 107 | page.go(page.route) 108 | -------------------------------------------------------------------------------- /kintree/gui/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/kintree/gui/logo.ico -------------------------------------------------------------------------------- /kintree/kicad/kicad_interface.py: -------------------------------------------------------------------------------- 1 | from . import kicad_symbol 2 | 3 | 4 | def inventree_to_kicad(part_data: dict, library_path: str, template_path=None, show_progress=True) -> bool: 5 | ''' Create KiCad symbol from InvenTree part data ''' 6 | klib = kicad_symbol.ComponentLibManager(library_path) 7 | return klib.add_symbol_to_library_from_inventree( 8 | symbol_data=part_data, 9 | template_path=template_path, 10 | show_progress=show_progress 11 | ) 12 | -------------------------------------------------------------------------------- /kintree/kicad/kicad_symbol.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..config import settings 4 | from ..common import progress 5 | from ..common.tools import cprint 6 | from kiutils.symbol import SymbolLib 7 | 8 | 9 | # KiCad Component Library Manager 10 | class ComponentLibManager(object): 11 | def __init__(self, library_path): 12 | # Load library and template paths 13 | cprint(f'[KCAD]\tlibrary_path: {library_path}', silent=settings.SILENT) 14 | 15 | # Check files exist 16 | if not os.path.isfile(library_path): 17 | cprint(f'[KCAD]\tError loading library file ({library_path})', silent=settings.SILENT) 18 | return None 19 | 20 | # Load library 21 | self.kicad_lib = SymbolLib.from_file(library_path) 22 | self.library_name = library_path.split(os.sep)[-1] 23 | cprint('[KCAD]\tNumber of parts in library ' + self.library_name + ': ' + str(len(self.kicad_lib.symbols)), silent=settings.SILENT) 24 | 25 | def is_symbol_in_library(self, symbol_id): 26 | ''' Check if symbol already exists in library ''' 27 | for symbol in self.kicad_lib.symbols: 28 | cprint(f'[DBUG]\t{symbol.libId} ?= {symbol_id}', silent=settings.HIDE_DEBUG) 29 | if symbol.libId == symbol_id: 30 | cprint(f'[KCAD]\tWarning: Component {symbol_id} already in library', silent=settings.SILENT) 31 | return True 32 | 33 | return False 34 | 35 | def add_symbol_to_library_from_inventree(self, symbol_data, template_path=None, show_progress=True): 36 | ''' Create symbol in KiCad library ''' 37 | part_in_lib = False 38 | new_part = False 39 | part_name = '' 40 | parameters = symbol_data.get('parameters', {}) 41 | parameters = {**symbol_data, **parameters} 42 | key_list = list(parameters.keys()) 43 | key_list.sort(key=len, reverse=True) 44 | 45 | def replace_wildcards(field): 46 | for key in key_list: 47 | if key in field: 48 | field = field.replace(key, parameters[key]) 49 | return field 50 | 51 | symbol_id = symbol_data.get('Symbol', '').split(':') 52 | if not symbol_id: 53 | cprint('[KCAD] Error: Adding a new symbol to a KiCad library requires the \'Symbol\' key with the following format: {lib}:{symbol_id}') 54 | return part_in_lib, new_part, part_name 55 | 56 | if not template_path: 57 | category = symbol_data['Template'][0] 58 | subcategory = symbol_data['Template'][1] 59 | 60 | # Fetch template path 61 | try: 62 | template_path = settings.symbol_templates_paths[category][subcategory] 63 | except: 64 | template_path = settings.symbol_templates_paths[category]['Default'] 65 | 66 | # Check files exist 67 | if not self.kicad_lib: 68 | return part_in_lib, new_part 69 | if not os.path.isfile(template_path): 70 | cprint(f'[KCAD]\tError loading template file ({template_path})', silent=settings.SILENT) 71 | return part_in_lib, new_part, part_name 72 | 73 | # Load template 74 | templatelib = SymbolLib.from_file(template_path) 75 | # Load new symbol 76 | if len(templatelib.symbols) == 1: 77 | for symbol in templatelib.symbols: 78 | new_symbol = symbol 79 | else: 80 | cprint('[KCAD]\tError: Found more than 1 symbol template in template file, aborting', silent=settings.SILENT) 81 | return part_in_lib, new_part, part_name 82 | 83 | # Update name/ID 84 | part_name = replace_wildcards(new_symbol.libId) 85 | new_symbol.libId = part_name 86 | 87 | # Check if part already in library 88 | try: 89 | is_symbol_in_library = self.is_symbol_in_library(part_name) 90 | part_in_lib = True 91 | except: 92 | is_symbol_in_library = False 93 | if is_symbol_in_library: 94 | return part_in_lib, new_part, part_name 95 | 96 | # Progress Update 97 | if not progress.update_progress_bar(show_progress): 98 | return part_in_lib, new_part, part_name 99 | 100 | # Update properties 101 | for property in new_symbol.properties: 102 | property.value = replace_wildcards(property.value) 103 | 104 | # Add symbol to library 105 | self.kicad_lib.symbols.append(new_symbol) 106 | # Write library 107 | self.kicad_lib.to_file() 108 | 109 | cprint(f'[KCAD]\tSuccess: Component added to library {self.library_name}', silent=settings.SILENT) 110 | part_in_lib = True 111 | new_part = True 112 | 113 | # Progress Update 114 | if not progress.update_progress_bar(show_progress): 115 | pass 116 | 117 | return part_in_lib, new_part, part_name 118 | -------------------------------------------------------------------------------- /kintree/kicad/templates/LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /kintree/kicad/templates/capacitor-polarized.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "C" (at 0 3.81 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -11.43 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -19.05 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -21.59 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -13.97 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -16.51 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Capacitance (Farad)" "Value" (at 0 -3.81 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Tolerance (%)" "Tolerance" (at 5.08 -3.81 0) 25 | (effects (font (size 1.27 1.27)) (justify left) hide) 26 | ) 27 | (property "Voltage Rated (Volt)" "Rated Voltage" (at 0 -6.35 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "Package Type" "Package Type" (at 0 -8.89 0) 31 | (effects (font (size 1.27 1.27))) 32 | ) 33 | (property "Package Size" "Package Size" (at 0 -8.89 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ESR (Ohm)" "ESR" (at 5.08 -6.35 0) 37 | (effects (font (size 1.27 1.27)) (justify left) hide) 38 | ) 39 | (property "ki_keywords" "keywords" (at 0 0 0) 40 | (effects (font (size 1.27 1.27)) hide) 41 | ) 42 | (property "ki_description" "description" (at 0 0 0) 43 | (effects (font (size 1.27 1.27)) hide) 44 | ) 45 | (symbol "IPN_0_1" 46 | (polyline 47 | (pts 48 | (xy -1.778 -0.381) 49 | (xy -1.778 -1.651) 50 | ) 51 | (stroke (width 0) (type default)) 52 | (fill (type none)) 53 | ) 54 | (polyline 55 | (pts 56 | (xy -1.27 0) 57 | (xy -0.635 0) 58 | ) 59 | (stroke (width 0) (type default)) 60 | (fill (type none)) 61 | ) 62 | (polyline 63 | (pts 64 | (xy -1.143 -1.016) 65 | (xy -2.413 -1.016) 66 | ) 67 | (stroke (width 0) (type default)) 68 | (fill (type none)) 69 | ) 70 | (polyline 71 | (pts 72 | (xy -0.635 -1.905) 73 | (xy -0.635 1.905) 74 | ) 75 | (stroke (width 0.254) (type default)) 76 | (fill (type none)) 77 | ) 78 | (polyline 79 | (pts 80 | (xy 1.524 0) 81 | (xy 0.635 0) 82 | ) 83 | (stroke (width 0) (type default)) 84 | (fill (type none)) 85 | ) 86 | (arc (start 1.524 1.905) (mid 0.8343 0) (end 1.524 -1.905) 87 | (stroke (width 0.254) (type default)) 88 | (fill (type none)) 89 | ) 90 | ) 91 | (symbol "IPN_1_1" 92 | (pin passive line (at -3.81 0 0) (length 2.54) 93 | (name "Positif" (effects (font (size 1.27 1.27)))) 94 | (number "1" (effects (font (size 1.27 1.27)))) 95 | ) 96 | (pin passive line (at 3.81 0 180) (length 2.54) 97 | (name "Negatif" (effects (font (size 1.27 1.27)))) 98 | (number "2" (effects (font (size 1.27 1.27)))) 99 | ) 100 | ) 101 | ) 102 | ) 103 | -------------------------------------------------------------------------------- /kintree/kicad/templates/capacitor.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "C" (at 0 3.81 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -13.97 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -21.59 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -24.13 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -16.51 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -19.05 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Capacitance (Farad)" "Value" (at 0 -3.81 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Tolerance (%)" "Tolerance" (at 7.62 -3.81 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 0 -6.35 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "Temperature Grade" "Temperature Grade" (at 0 -11.43 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "Package Type" "Package Type" (at 0 -8.89 0) 34 | (effects (font (size 1.27 1.27))) 35 | ) 36 | (property "ki_keywords" "keywords" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (property "ki_description" "description" (at 0 0 0) 40 | (effects (font (size 1.27 1.27)) hide) 41 | ) 42 | (symbol "IPN_0_1" 43 | (polyline 44 | (pts 45 | (xy -1.27 0) 46 | (xy -1.016 0) 47 | ) 48 | (stroke (width 0) (type default)) 49 | (fill (type none)) 50 | ) 51 | (polyline 52 | (pts 53 | (xy -0.889 1.905) 54 | (xy -0.889 -1.905) 55 | ) 56 | (stroke (width 0.254) (type default)) 57 | (fill (type none)) 58 | ) 59 | (polyline 60 | (pts 61 | (xy 0.889 1.905) 62 | (xy 0.889 -1.905) 63 | ) 64 | (stroke (width 0.254) (type default)) 65 | (fill (type none)) 66 | ) 67 | (polyline 68 | (pts 69 | (xy 1.27 0) 70 | (xy 1.016 0) 71 | ) 72 | (stroke (width 0) (type default)) 73 | (fill (type none)) 74 | ) 75 | (polyline 76 | (pts 77 | (xy 1.905 0) 78 | (xy 2.54 0) 79 | ) 80 | (stroke (width 0) (type default)) 81 | (fill (type none)) 82 | ) 83 | ) 84 | (symbol "IPN_1_1" 85 | (pin passive line (at -3.81 0 0) (length 2.54) 86 | (name "1" (effects (font (size 1.27 1.27)))) 87 | (number "1" (effects (font (size 1.27 1.27)))) 88 | ) 89 | (pin passive line (at 3.81 0 180) (length 2.54) 90 | (name "2" (effects (font (size 1.27 1.27)))) 91 | (number "2" (effects (font (size 1.27 1.27)))) 92 | ) 93 | ) 94 | ) 95 | ) 96 | -------------------------------------------------------------------------------- /kintree/kicad/templates/connector.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "J" (at 0 0 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -5.08 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -12.7 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -15.24 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -7.62 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -10.16 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -2.54 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "ki_keywords" "keywords" (at 0 0 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "ki_description" "description" (at 0 0 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | ) 31 | ) 32 | -------------------------------------------------------------------------------- /kintree/kicad/templates/crystal-2p.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "Y" (at 0 5.08 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -15.24 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -20.32 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -22.86 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -17.78 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -7.62 0) 19 | (effects (font (size 1.27 1.27))) 20 | ) 21 | (property "Frequency" "Value" (at 0 -5.08 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Load Capacitance (Farad)" "Load Capacitance" (at 0 -10.16 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "Package Size" "Package Size" (at 0 -12.7 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | (property "ki_keywords" "keywords" (at 0 0 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_description" "description" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (symbol "IPN_1_1" 37 | (rectangle (start -1.016 3.048) (end 1.016 -3.048) 38 | (stroke (width 0.254) (type default)) 39 | (fill (type none)) 40 | ) 41 | (polyline 42 | (pts 43 | (xy -2.54 0) 44 | (xy -1.778 0) 45 | ) 46 | (stroke (width 0) (type default)) 47 | (fill (type none)) 48 | ) 49 | (polyline 50 | (pts 51 | (xy 2.54 0) 52 | (xy 1.778 0) 53 | ) 54 | (stroke (width 0) (type default)) 55 | (fill (type none)) 56 | ) 57 | (polyline 58 | (pts 59 | (xy -1.778 2.54) 60 | (xy -1.778 0) 61 | (xy -1.778 -2.54) 62 | ) 63 | (stroke (width 0) (type default)) 64 | (fill (type none)) 65 | ) 66 | (polyline 67 | (pts 68 | (xy 1.778 2.54) 69 | (xy 1.778 0) 70 | (xy 1.778 -2.54) 71 | ) 72 | (stroke (width 0) (type default)) 73 | (fill (type none)) 74 | ) 75 | (pin passive line (at -5.08 0 0) (length 2.54) 76 | (name "1" (effects (font (size 1.27 1.27)))) 77 | (number "1" (effects (font (size 1.27 1.27)))) 78 | ) 79 | (pin passive line (at 5.08 0 180) (length 2.54) 80 | (name "2" (effects (font (size 1.27 1.27)))) 81 | (number "2" (effects (font (size 1.27 1.27)))) 82 | ) 83 | ) 84 | ) 85 | ) 86 | -------------------------------------------------------------------------------- /kintree/kicad/templates/default.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "DES" (at 0 0 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -5.08 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -12.7 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -15.24 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -7.62 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -10.16 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -2.54 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "ki_keywords" "keywords" (at 0 0 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "ki_description" "description" (at 0 0 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | ) 31 | ) 32 | -------------------------------------------------------------------------------- /kintree/kicad/templates/diode-led.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "D" (at 0 3.81 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -12.7 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -20.32 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -22.86 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -15.24 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -17.78 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -10.16 0) 22 | (effects (font (size 1.27 1.27)) hide) 23 | ) 24 | (property "Forward Voltage (Volt)" "Forward Voltage" (at 0 -7.62 0) 25 | (effects (font (size 1.27 1.27))) 26 | ) 27 | (property "LED Color" "LED Color" (at 0 -5.08 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "ki_keywords" "keywords" (at 0 0 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_description" "description" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (symbol "IPN_0_1" 37 | (polyline 38 | (pts 39 | (xy 1.27 -1.27) 40 | (xy 1.27 1.27) 41 | ) 42 | (stroke (width 0.381) (type default)) 43 | (fill (type none)) 44 | ) 45 | (polyline 46 | (pts 47 | (xy -1.27 1.27) 48 | (xy -1.27 -1.27) 49 | (xy 1.27 0) 50 | (xy -1.27 1.27) 51 | ) 52 | (stroke (width 0.254) (type default)) 53 | (fill (type background)) 54 | ) 55 | (polyline 56 | (pts 57 | (xy -0.889 -1.778) 58 | (xy 0.508 -3.175) 59 | (xy 0.254 -2.413) 60 | (xy -0.254 -2.921) 61 | (xy 0.508 -3.175) 62 | ) 63 | (stroke (width 0.254) (type default)) 64 | (fill (type outline)) 65 | ) 66 | (polyline 67 | (pts 68 | (xy 0.635 -1.651) 69 | (xy 2.032 -3.048) 70 | (xy 1.27 -2.794) 71 | (xy 1.778 -2.286) 72 | (xy 2.032 -3.048) 73 | ) 74 | (stroke (width 0.254) (type default)) 75 | (fill (type outline)) 76 | ) 77 | ) 78 | (symbol "IPN_1_1" 79 | (pin passive line (at 3.81 0 180) (length 2.54) 80 | (name "Cathode" (effects (font (size 1.27 1.27)))) 81 | (number "1" (effects (font (size 1.27 1.27)))) 82 | ) 83 | (pin passive line (at -3.81 0 0) (length 2.54) 84 | (name "Anode" (effects (font (size 1.27 1.27)))) 85 | (number "2" (effects (font (size 1.27 1.27)))) 86 | ) 87 | ) 88 | ) 89 | ) 90 | -------------------------------------------------------------------------------- /kintree/kicad/templates/diode-schottky.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "D" (at 0 3.81 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -13.97 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -21.59 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -24.13 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -16.51 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -19.05 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -3.81 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Forward Voltage (Volt)" "Forward Voltage" (at 0 -8.89 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "Current (Amps)" "Rated Current" (at 0 -6.35 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 0 -11.43 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 -1.397) 43 | (xy 2.159 -1.397) 44 | ) 45 | (stroke (width 0.254) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy 1.27 -1.397) 51 | (xy 1.27 1.397) 52 | (xy 0.381 1.397) 53 | ) 54 | (stroke (width 0.254) (type default)) 55 | (fill (type none)) 56 | ) 57 | (polyline 58 | (pts 59 | (xy -1.27 1.27) 60 | (xy -1.27 -1.27) 61 | (xy 1.27 0) 62 | (xy -1.27 1.27) 63 | ) 64 | (stroke (width 0.254) (type default)) 65 | (fill (type background)) 66 | ) 67 | ) 68 | (symbol "IPN_1_1" 69 | (pin passive line (at 3.81 0 180) (length 2.54) 70 | (name "Cathode" (effects (font (size 1.27 1.27)))) 71 | (number "1" (effects (font (size 1.27 1.27)))) 72 | ) 73 | (pin passive line (at -3.81 0 0) (length 2.54) 74 | (name "Anode" (effects (font (size 1.27 1.27)))) 75 | (number "2" (effects (font (size 1.27 1.27)))) 76 | ) 77 | ) 78 | ) 79 | ) 80 | -------------------------------------------------------------------------------- /kintree/kicad/templates/diode-standard.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "D" (at 0 3.81 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -13.97 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -21.59 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -24.13 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -16.51 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -19.05 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -3.81 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Forward Voltage (Volt)" "Forward Voltage" (at 0 -8.89 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "Current (Amps)" "Rated Current" (at 0 -6.35 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 0 -11.43 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 -1.397) 43 | (xy 1.27 1.397) 44 | ) 45 | (stroke (width 0.254) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy -1.27 1.27) 51 | (xy -1.27 -1.27) 52 | (xy 1.27 0) 53 | (xy -1.27 1.27) 54 | ) 55 | (stroke (width 0.254) (type default)) 56 | (fill (type background)) 57 | ) 58 | ) 59 | (symbol "IPN_1_1" 60 | (pin passive line (at 3.81 0 180) (length 2.54) 61 | (name "Cathode" (effects (font (size 1.27 1.27)))) 62 | (number "1" (effects (font (size 1.27 1.27)))) 63 | ) 64 | (pin passive line (at -3.81 0 0) (length 2.54) 65 | (name "Anode" (effects (font (size 1.27 1.27)))) 66 | (number "2" (effects (font (size 1.27 1.27)))) 67 | ) 68 | ) 69 | ) 70 | ) 71 | -------------------------------------------------------------------------------- /kintree/kicad/templates/diode-zener.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "D" (at 0 3.81 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -13.97 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -21.59 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -24.13 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -16.51 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -19.05 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -3.81 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Forward Voltage (Volt)" "Forward Voltage" (at 0 -11.43 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "Power (Watts)" "Rated Power" (at 0 -6.35 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 0 -8.89 0) 31 | (effects (font (size 1.27 1.27))) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 -1.397) 43 | (xy 2.159 -1.778) 44 | ) 45 | (stroke (width 0.254) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy 1.27 -1.397) 51 | (xy 1.27 1.397) 52 | (xy 0.381 1.778) 53 | ) 54 | (stroke (width 0.254) (type default)) 55 | (fill (type none)) 56 | ) 57 | (polyline 58 | (pts 59 | (xy -1.27 1.27) 60 | (xy -1.27 -1.27) 61 | (xy 1.27 0) 62 | (xy -1.27 1.27) 63 | ) 64 | (stroke (width 0.254) (type default)) 65 | (fill (type background)) 66 | ) 67 | ) 68 | (symbol "IPN_1_1" 69 | (pin passive line (at 3.81 0 180) (length 2.54) 70 | (name "Cathode" (effects (font (size 1.27 1.27)))) 71 | (number "1" (effects (font (size 1.27 1.27)))) 72 | ) 73 | (pin passive line (at -3.81 0 0) (length 2.54) 74 | (name "Anode" (effects (font (size 1.27 1.27)))) 75 | (number "2" (effects (font (size 1.27 1.27)))) 76 | ) 77 | ) 78 | ) 79 | ) 80 | -------------------------------------------------------------------------------- /kintree/kicad/templates/eeprom-sot23.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (in_bom yes) (on_board yes) 3 | (property "Reference" "U" (at 0 8.89 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -11.43 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -19.05 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -21.59 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -13.97 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -16.51 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -8.89 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "ki_keywords" "keywords" (at 0 0 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "ki_description" "description" (at 0 0 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | (symbol "IPN_0_1" 31 | (rectangle (start -5.08 7.62) (end 5.08 -7.62) 32 | (stroke (width 0.254) (type default)) 33 | (fill (type background)) 34 | ) 35 | ) 36 | (symbol "IPN_1_1" 37 | (pin passive line (at -7.62 0 0) (length 2.54) 38 | (name "SCL" (effects (font (size 1.27 1.27)))) 39 | (number "1" (effects (font (size 1.27 1.27)))) 40 | ) 41 | (pin power_in line (at 7.62 -5.08 180) (length 2.54) 42 | (name "VSS" (effects (font (size 1.27 1.27)))) 43 | (number "2" (effects (font (size 1.27 1.27)))) 44 | ) 45 | (pin passive line (at -7.62 -5.08 0) (length 2.54) 46 | (name "SDA" (effects (font (size 1.27 1.27)))) 47 | (number "3" (effects (font (size 1.27 1.27)))) 48 | ) 49 | (pin power_in line (at -7.62 5.08 0) (length 2.54) 50 | (name "VCC" (effects (font (size 1.27 1.27)))) 51 | (number "4" (effects (font (size 1.27 1.27)))) 52 | ) 53 | (pin passive line (at 7.62 5.08 180) (length 2.54) 54 | (name "WP" (effects (font (size 1.27 1.27)))) 55 | (number "5" (effects (font (size 1.27 1.27)))) 56 | ) 57 | ) 58 | ) 59 | ) 60 | -------------------------------------------------------------------------------- /kintree/kicad/templates/ferrite-bead.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "FB" (at 0 2.54 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Inductance (Henry)" "Value" (at 0 -2.54 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Current Rating (Ampere)" "Rated Current" (at 0 -5.08 0) 25 | (effects (font (size 1.27 1.27))) 26 | ) 27 | (property "ESR (Ohm)" "ESR" (at 0 -7.62 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | (property "ki_keywords" "keywords" (at 0 0 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_description" "description" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (symbol "IPN_0_1" 37 | (polyline 38 | (pts 39 | (xy -4.318 0) 40 | (xy -4.064 0) 41 | ) 42 | (stroke (width 0) (type default)) 43 | (fill (type none)) 44 | ) 45 | (polyline 46 | (pts 47 | (xy -1.27 0) 48 | (xy 1.27 0) 49 | ) 50 | (stroke (width 0) (type default)) 51 | (fill (type none)) 52 | ) 53 | (polyline 54 | (pts 55 | (xy 4.064 0) 56 | (xy 4.318 0) 57 | ) 58 | (stroke (width 0) (type default)) 59 | (fill (type none)) 60 | ) 61 | (polyline 62 | (pts 63 | (xy -2.54 1.27) 64 | (xy -2.54 -1.27) 65 | (xy 2.54 -1.27) 66 | (xy 2.54 1.27) 67 | (xy -2.54 1.27) 68 | ) 69 | (stroke (width 0) (type default)) 70 | (fill (type none)) 71 | ) 72 | ) 73 | (symbol "IPN_1_1" 74 | (pin passive line (at -5.08 0 0) (length 2.54) 75 | (name "1" (effects (font (size 1.27 1.27)))) 76 | (number "1" (effects (font (size 1.27 1.27)))) 77 | ) 78 | (pin passive line (at 5.08 0 180) (length 2.54) 79 | (name "2" (effects (font (size 1.27 1.27)))) 80 | (number "2" (effects (font (size 1.27 1.27)))) 81 | ) 82 | ) 83 | ) 84 | ) 85 | -------------------------------------------------------------------------------- /kintree/kicad/templates/fuse.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "F" (at 0 2.794 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Current Rating (A)" "Rated Current" (at 0 -2.54 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Voltage Rating (V)" "Rated Voltage" (at 0 -5.08 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "Package Type" "Package Type" (at 0 -7.62 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | (property "ki_keywords" "keywords" (at 0 0 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_description" "description" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (symbol "IPN_0_1" 37 | (rectangle (start -3.81 0) (end -3.048 0) 38 | (stroke (width 0) (type default)) 39 | (fill (type none)) 40 | ) 41 | (arc (start 0 0) (mid 1.524 -1.5174) (end 3.048 0) 42 | (stroke (width 0) (type default)) 43 | (fill (type none)) 44 | ) 45 | (rectangle (start 3.048 0) (end 3.81 0) 46 | (stroke (width 0) (type default)) 47 | (fill (type none)) 48 | ) 49 | ) 50 | (symbol "IPN_1_1" 51 | (arc (start 0 0) (mid -1.524 1.5174) (end -3.048 0) 52 | (stroke (width 0) (type default)) 53 | (fill (type none)) 54 | ) 55 | (pin passive line (at -5.08 0 0) (length 1.27) 56 | (name "1" (effects (font (size 1.27 1.27)))) 57 | (number "1" (effects (font (size 1.27 1.27)))) 58 | ) 59 | (pin passive line (at 5.08 0 180) (length 1.27) 60 | (name "2" (effects (font (size 1.27 1.27)))) 61 | (number "2" (effects (font (size 1.27 1.27)))) 62 | ) 63 | ) 64 | ) 65 | ) 66 | -------------------------------------------------------------------------------- /kintree/kicad/templates/inductor.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "L" (at 0 2.54 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -8.89 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -16.51 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -19.05 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -11.43 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -13.97 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Inductance (Henry)" "Value" (at 0 -1.27 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Current Rating (Ampere)" "Rated Current" (at 0 -3.81 0) 25 | (effects (font (size 1.27 1.27))) 26 | ) 27 | (property "ESR (Ohm)" "ESR" (at 0 -6.35 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | (property "ki_keywords" "keywords" (at 0 0 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_description" "description" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (symbol "IPN_0_1" 37 | (arc (start -1.905 0) (mid -2.8575 0.9399) (end -3.81 0) 38 | (stroke (width 0) (type default)) 39 | (fill (type none)) 40 | ) 41 | (arc (start 0 0) (mid -0.9525 0.9399) (end -1.905 0) 42 | (stroke (width 0) (type default)) 43 | (fill (type none)) 44 | ) 45 | (arc (start 1.905 0) (mid 0.9525 0.9399) (end 0 0) 46 | (stroke (width 0) (type default)) 47 | (fill (type none)) 48 | ) 49 | (arc (start 3.81 0) (mid 2.8575 0.9399) (end 1.905 0) 50 | (stroke (width 0) (type default)) 51 | (fill (type none)) 52 | ) 53 | ) 54 | (symbol "IPN_1_1" 55 | (pin passive line (at -6.35 0 0) (length 2.54) 56 | (name "1" (effects (font (size 1.27 1.27)))) 57 | (number "1" (effects (font (size 1.27 1.27)))) 58 | ) 59 | (pin passive line (at 6.35 0 180) (length 2.54) 60 | (name "2" (effects (font (size 1.27 1.27)))) 61 | (number "2" (effects (font (size 1.27 1.27)))) 62 | ) 63 | ) 64 | ) 65 | ) 66 | -------------------------------------------------------------------------------- /kintree/kicad/templates/integrated-circuit.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "U" (at 0 0 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -5.08 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -12.7 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -15.24 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -7.62 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -10.16 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -2.54 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "ki_keywords" "keywords" (at 0 0 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "ki_description" "description" (at 0 0 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | ) 31 | ) 32 | -------------------------------------------------------------------------------- /kintree/kicad/templates/library_template.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20211014) (generator kicad_converter)) -------------------------------------------------------------------------------- /kintree/kicad/templates/oscillator-4p.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (in_bom yes) (on_board yes) 3 | (property "Reference" "Y" (at 0 6.35 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -16.51 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -21.59 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -24.13 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -19.05 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -8.89 0) 19 | (effects (font (size 1.27 1.27))) 20 | ) 21 | (property "Part Number" "Value" (at 0 -6.35 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 0 -11.43 0) 25 | (effects (font (size 1.27 1.27)) hide) 26 | ) 27 | (property "Package Size" "Package Size" (at 0 -13.97 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | (property "ki_keywords" "keywords" (at 0 0 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_description" "description" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (symbol "IPN_1_1" 37 | (rectangle (start -5.08 5.08) (end 5.08 -5.08) 38 | (stroke (width 0) (type default)) 39 | (fill (type background)) 40 | ) 41 | (pin input line (at -10.16 -2.54 0) (length 5.08) 42 | (name "OE" (effects (font (size 1.27 1.27)))) 43 | (number "1" (effects (font (size 1.27 1.27)))) 44 | ) 45 | (pin power_out line (at 10.16 -2.54 180) (length 5.08) 46 | (name "GND" (effects (font (size 1.27 1.27)))) 47 | (number "2" (effects (font (size 1.27 1.27)))) 48 | ) 49 | (pin output line (at 10.16 2.54 180) (length 5.08) 50 | (name "OUT" (effects (font (size 1.27 1.27)))) 51 | (number "3" (effects (font (size 1.27 1.27)))) 52 | ) 53 | (pin power_in line (at -10.16 2.54 0) (length 5.08) 54 | (name "VDD" (effects (font (size 1.27 1.27)))) 55 | (number "4" (effects (font (size 1.27 1.27)))) 56 | ) 57 | ) 58 | ) 59 | ) 60 | -------------------------------------------------------------------------------- /kintree/kicad/templates/protection-unidir.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "D" (at 0 3.81 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -13.97 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -21.59 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -24.13 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -16.51 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -19.05 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 0 -3.81 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Standoff Voltage" "Standoff Voltage" (at 0 -6.35 0) 25 | (effects (font (size 1.27 1.27))) 26 | ) 27 | (property "Breakdown Voltage" "Breakdown Voltage" (at 0 -8.89 0) 28 | (effects (font (size 1.27 1.27)) hide) 29 | ) 30 | (property "Peak Power (Watts)" "Rated Power" (at 0 -11.43 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 -1.397) 43 | (xy 2.159 -1.778) 44 | ) 45 | (stroke (width 0.254) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy 1.27 -1.397) 51 | (xy 1.27 1.397) 52 | (xy 0.381 1.778) 53 | ) 54 | (stroke (width 0.254) (type default)) 55 | (fill (type none)) 56 | ) 57 | (polyline 58 | (pts 59 | (xy -1.27 1.27) 60 | (xy -1.27 -1.27) 61 | (xy 1.27 0) 62 | (xy -1.27 1.27) 63 | ) 64 | (stroke (width 0.254) (type default)) 65 | (fill (type background)) 66 | ) 67 | ) 68 | (symbol "IPN_1_1" 69 | (pin passive line (at 3.81 0 180) (length 2.54) 70 | (name "Cathode" (effects (font (size 1.27 1.27)))) 71 | (number "1" (effects (font (size 1.27 1.27)))) 72 | ) 73 | (pin passive line (at -3.81 0 0) (length 2.54) 74 | (name "Anode" (effects (font (size 1.27 1.27)))) 75 | (number "2" (effects (font (size 1.27 1.27)))) 76 | ) 77 | ) 78 | ) 79 | ) 80 | -------------------------------------------------------------------------------- /kintree/kicad/templates/resistor-sm.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "R" (at 0 2.032 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Resistance (Ohms)" "Value" (at 0 -2.54 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Tolerance (%)" "Tolerance" (at 3.81 -2.54 0) 25 | (effects (font (size 1.27 1.27)) (justify left) hide) 26 | ) 27 | (property "Package Type" "Package Type" (at 0 -5.08 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "Power (Watts)" "Rated Power" (at 0 -7.62 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy -3.81 0) 43 | (xy -3.048 0) 44 | (xy -2.54 0.762) 45 | (xy -1.524 -0.762) 46 | (xy -0.508 0.762) 47 | (xy 0.508 -0.762) 48 | (xy 1.524 0.762) 49 | (xy 2.54 -0.762) 50 | (xy 3.048 0) 51 | (xy 3.81 0) 52 | (xy 3.81 0) 53 | ) 54 | (stroke (width 0) (type default)) 55 | (fill (type none)) 56 | ) 57 | ) 58 | (symbol "IPN_1_1" 59 | (pin passive line (at -5.08 0 0) (length 1.27) 60 | (name "1" (effects (font (size 1.27 1.27)))) 61 | (number "1" (effects (font (size 1.27 1.27)))) 62 | ) 63 | (pin passive line (at 5.08 0 180) (length 1.27) 64 | (name "2" (effects (font (size 1.27 1.27)))) 65 | (number "2" (effects (font (size 1.27 1.27)))) 66 | ) 67 | ) 68 | ) 69 | ) 70 | -------------------------------------------------------------------------------- /kintree/kicad/templates/resistor.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "R" (at 0 2.032 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Resistance (Ohms)" "Value" (at 0 -2.54 0) 22 | (effects (font (size 1.27 1.27))) 23 | ) 24 | (property "Tolerance (%)" "Tolerance" (at 3.81 -2.54 0) 25 | (effects (font (size 1.27 1.27)) (justify left) hide) 26 | ) 27 | (property "Package Type" "Package Type" (at 0 -5.08 0) 28 | (effects (font (size 1.27 1.27))) 29 | ) 30 | (property "Power (Watts)" "Rated Power" (at 0 -7.62 0) 31 | (effects (font (size 1.27 1.27)) hide) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy -3.81 0) 43 | (xy -3.048 0) 44 | (xy -2.54 0.762) 45 | (xy -1.524 -0.762) 46 | (xy -0.508 0.762) 47 | (xy 0.508 -0.762) 48 | (xy 1.524 0.762) 49 | (xy 2.54 -0.762) 50 | (xy 3.048 0) 51 | (xy 3.81 0) 52 | (xy 3.81 0) 53 | ) 54 | (stroke (width 0) (type default)) 55 | (fill (type none)) 56 | ) 57 | ) 58 | (symbol "IPN_1_1" 59 | (pin passive line (at -5.08 0 0) (length 1.27) 60 | (name "1" (effects (font (size 1.27 1.27)))) 61 | (number "1" (effects (font (size 1.27 1.27)))) 62 | ) 63 | (pin passive line (at 5.08 0 180) (length 1.27) 64 | (name "2" (effects (font (size 1.27 1.27)))) 65 | (number "2" (effects (font (size 1.27 1.27)))) 66 | ) 67 | ) 68 | ) 69 | ) 70 | -------------------------------------------------------------------------------- /kintree/kicad/templates/transistor-nfet.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "Q" (at 0 4.318 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 7.62 3.81 0) 22 | (effects (font (size 1.27 1.27)) (justify left)) 23 | ) 24 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 7.62 1.27 0) 25 | (effects (font (size 1.27 1.27)) (justify left)) 26 | ) 27 | (property "Rated Current (Amps)" "Rated Current" (at 7.62 -1.27 0) 28 | (effects (font (size 1.27 1.27)) (justify left)) 29 | ) 30 | (property "Package Type" "Package Type" (at 7.62 -3.81 0) 31 | (effects (font (size 1.27 1.27)) (justify left)) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 0) 43 | (xy 1.27 -2.54) 44 | ) 45 | (stroke (width 0) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy 1.27 0) 51 | (xy 1.27 2.54) 52 | ) 53 | (stroke (width 0) (type default)) 54 | (fill (type none)) 55 | ) 56 | (polyline 57 | (pts 58 | (xy 1.778 -1.27) 59 | (xy 1.778 -2.54) 60 | ) 61 | (stroke (width 0) (type default)) 62 | (fill (type none)) 63 | ) 64 | (polyline 65 | (pts 66 | (xy 1.778 -0.635) 67 | (xy 1.778 0.635) 68 | ) 69 | (stroke (width 0) (type default)) 70 | (fill (type none)) 71 | ) 72 | (polyline 73 | (pts 74 | (xy 1.778 1.27) 75 | (xy 1.778 2.54) 76 | ) 77 | (stroke (width 0) (type default)) 78 | (fill (type none)) 79 | ) 80 | (polyline 81 | (pts 82 | (xy 3.81 -2.54) 83 | (xy 3.81 -1.905) 84 | ) 85 | (stroke (width 0) (type default)) 86 | (fill (type none)) 87 | ) 88 | (polyline 89 | (pts 90 | (xy 4.953 0.508) 91 | (xy 6.223 0.508) 92 | ) 93 | (stroke (width 0.127) (type default)) 94 | (fill (type none)) 95 | ) 96 | (polyline 97 | (pts 98 | (xy 5.08 -0.635) 99 | (xy 4.953 -0.635) 100 | ) 101 | (stroke (width 0) (type default)) 102 | (fill (type none)) 103 | ) 104 | (polyline 105 | (pts 106 | (xy 1.778 1.905) 107 | (xy 3.81 1.905) 108 | (xy 3.81 2.54) 109 | ) 110 | (stroke (width 0) (type default)) 111 | (fill (type none)) 112 | ) 113 | (polyline 114 | (pts 115 | (xy 5.588 -0.635) 116 | (xy 5.588 -2.413) 117 | (xy 3.81 -2.413) 118 | ) 119 | (stroke (width 0) (type default)) 120 | (fill (type none)) 121 | ) 122 | (polyline 123 | (pts 124 | (xy 5.588 0.635) 125 | (xy 5.588 2.286) 126 | (xy 3.81 2.286) 127 | ) 128 | (stroke (width 0) (type default)) 129 | (fill (type none)) 130 | ) 131 | (polyline 132 | (pts 133 | (xy 1.778 -1.905) 134 | (xy 3.81 -1.905) 135 | (xy 3.81 0) 136 | (xy 3.048 0) 137 | ) 138 | (stroke (width 0) (type default)) 139 | (fill (type none)) 140 | ) 141 | (polyline 142 | (pts 143 | (xy 1.905 0) 144 | (xy 3.048 0.635) 145 | (xy 3.048 -0.635) 146 | (xy 1.905 0) 147 | ) 148 | (stroke (width 0) (type default)) 149 | (fill (type outline)) 150 | ) 151 | (polyline 152 | (pts 153 | (xy 4.953 -0.635) 154 | (xy 5.588 0.508) 155 | (xy 6.223 -0.635) 156 | (xy 5.08 -0.635) 157 | ) 158 | (stroke (width 0) (type default)) 159 | (fill (type outline)) 160 | ) 161 | ) 162 | (symbol "IPN_1_1" 163 | (pin bidirectional line (at 3.81 7.62 270) (length 5.08) 164 | (name "D" (effects (font (size 1.27 1.27)))) 165 | (number "~" (effects (font (size 1.27 1.27)))) 166 | ) 167 | (pin input line (at -3.81 0 0) (length 5.08) 168 | (name "G" (effects (font (size 1.27 1.27)))) 169 | (number "~" (effects (font (size 1.27 1.27)))) 170 | ) 171 | (pin bidirectional line (at 3.81 -7.62 90) (length 5.08) 172 | (name "S" (effects (font (size 1.27 1.27)))) 173 | (number "~" (effects (font (size 1.27 1.27)))) 174 | ) 175 | ) 176 | ) 177 | ) 178 | -------------------------------------------------------------------------------- /kintree/kicad/templates/transistor-npn.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "Q" (at 0 4.318 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 5.08 3.81 0) 22 | (effects (font (size 1.27 1.27)) (justify left)) 23 | ) 24 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 5.08 1.27 0) 25 | (effects (font (size 1.27 1.27)) (justify left)) 26 | ) 27 | (property "Rated Current (Amps)" "Rated Current" (at 5.08 -1.27 0) 28 | (effects (font (size 1.27 1.27)) (justify left)) 29 | ) 30 | (property "Package Type" "Package Type" (at 5.08 -3.81 0) 31 | (effects (font (size 1.27 1.27)) (justify left)) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 2.286) 43 | (xy 1.27 -2.286) 44 | ) 45 | (stroke (width 0) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy 3.81 -2.54) 51 | (xy 1.27 -1.016) 52 | ) 53 | (stroke (width 0) (type default)) 54 | (fill (type none)) 55 | ) 56 | (polyline 57 | (pts 58 | (xy 3.81 2.54) 59 | (xy 1.27 1.016) 60 | ) 61 | (stroke (width 0) (type default)) 62 | (fill (type none)) 63 | ) 64 | (polyline 65 | (pts 66 | (xy 3.81 -2.54) 67 | (xy 3.175 -1.27) 68 | (xy 2.413 -2.413) 69 | (xy 3.81 -2.54) 70 | ) 71 | (stroke (width 0) (type default)) 72 | (fill (type outline)) 73 | ) 74 | ) 75 | (symbol "IPN_1_1" 76 | (pin input line (at -3.81 0 0) (length 5.08) 77 | (name "B" (effects (font (size 1.27 1.27)))) 78 | (number "~" (effects (font (size 1.27 1.27)))) 79 | ) 80 | (pin input line (at 3.81 7.62 270) (length 5.08) 81 | (name "C" (effects (font (size 1.27 1.27)))) 82 | (number "~" (effects (font (size 1.27 1.27)))) 83 | ) 84 | (pin output line (at 3.81 -7.62 90) (length 5.08) 85 | (name "E" (effects (font (size 1.27 1.27)))) 86 | (number "~" (effects (font (size 1.27 1.27)))) 87 | ) 88 | ) 89 | ) 90 | ) 91 | -------------------------------------------------------------------------------- /kintree/kicad/templates/transistor-pfet.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "Q" (at 0 4.318 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 7.62 3.81 0) 22 | (effects (font (size 1.27 1.27)) (justify left)) 23 | ) 24 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 7.62 1.27 0) 25 | (effects (font (size 1.27 1.27)) (justify left)) 26 | ) 27 | (property "Rated Current (Amps)" "Rated Current" (at 7.62 -1.27 0) 28 | (effects (font (size 1.27 1.27)) (justify left)) 29 | ) 30 | (property "Package Type" "Package Type" (at 7.62 -3.81 0) 31 | (effects (font (size 1.27 1.27)) (justify left)) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 0) 43 | (xy 1.27 -2.54) 44 | ) 45 | (stroke (width 0) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy 1.27 0) 51 | (xy 1.27 2.54) 52 | ) 53 | (stroke (width 0) (type default)) 54 | (fill (type none)) 55 | ) 56 | (polyline 57 | (pts 58 | (xy 1.778 -1.905) 59 | (xy 3.81 -1.905) 60 | ) 61 | (stroke (width 0) (type default)) 62 | (fill (type none)) 63 | ) 64 | (polyline 65 | (pts 66 | (xy 1.778 -1.27) 67 | (xy 1.778 -2.54) 68 | ) 69 | (stroke (width 0) (type default)) 70 | (fill (type none)) 71 | ) 72 | (polyline 73 | (pts 74 | (xy 1.778 -0.635) 75 | (xy 1.778 0.635) 76 | ) 77 | (stroke (width 0) (type default)) 78 | (fill (type none)) 79 | ) 80 | (polyline 81 | (pts 82 | (xy 1.778 0) 83 | (xy 2.667 0) 84 | ) 85 | (stroke (width 0) (type default)) 86 | (fill (type none)) 87 | ) 88 | (polyline 89 | (pts 90 | (xy 1.778 1.27) 91 | (xy 1.778 2.54) 92 | ) 93 | (stroke (width 0) (type default)) 94 | (fill (type none)) 95 | ) 96 | (polyline 97 | (pts 98 | (xy 3.81 -2.54) 99 | (xy 3.81 -1.905) 100 | ) 101 | (stroke (width 0) (type default)) 102 | (fill (type none)) 103 | ) 104 | (polyline 105 | (pts 106 | (xy 4.953 -0.635) 107 | (xy 6.223 -0.635) 108 | ) 109 | (stroke (width 0.127) (type default)) 110 | (fill (type none)) 111 | ) 112 | (polyline 113 | (pts 114 | (xy 5.08 0.508) 115 | (xy 4.953 0.508) 116 | ) 117 | (stroke (width 0) (type default)) 118 | (fill (type none)) 119 | ) 120 | (polyline 121 | (pts 122 | (xy 1.778 1.905) 123 | (xy 3.81 1.905) 124 | (xy 3.81 2.54) 125 | ) 126 | (stroke (width 0) (type default)) 127 | (fill (type none)) 128 | ) 129 | (polyline 130 | (pts 131 | (xy 3.683 0) 132 | (xy 3.81 0) 133 | (xy 3.81 -1.905) 134 | ) 135 | (stroke (width 0) (type default)) 136 | (fill (type none)) 137 | ) 138 | (polyline 139 | (pts 140 | (xy 5.588 -0.635) 141 | (xy 5.588 -2.413) 142 | (xy 3.81 -2.413) 143 | ) 144 | (stroke (width 0) (type default)) 145 | (fill (type none)) 146 | ) 147 | (polyline 148 | (pts 149 | (xy 5.588 0.508) 150 | (xy 5.588 2.286) 151 | (xy 3.81 2.286) 152 | ) 153 | (stroke (width 0) (type default)) 154 | (fill (type none)) 155 | ) 156 | (polyline 157 | (pts 158 | (xy 3.683 0) 159 | (xy 2.667 0.762) 160 | (xy 2.667 -0.762) 161 | (xy 3.683 0) 162 | ) 163 | (stroke (width 0) (type default)) 164 | (fill (type outline)) 165 | ) 166 | (polyline 167 | (pts 168 | (xy 4.953 0.508) 169 | (xy 5.588 -0.635) 170 | (xy 6.223 0.508) 171 | (xy 5.08 0.508) 172 | ) 173 | (stroke (width 0) (type default)) 174 | (fill (type outline)) 175 | ) 176 | ) 177 | (symbol "IPN_1_1" 178 | (pin bidirectional line (at 3.81 7.62 270) (length 5.08) 179 | (name "D" (effects (font (size 1.27 1.27)))) 180 | (number "~" (effects (font (size 1.27 1.27)))) 181 | ) 182 | (pin input line (at -3.81 0 0) (length 5.08) 183 | (name "G" (effects (font (size 1.27 1.27)))) 184 | (number "~" (effects (font (size 1.27 1.27)))) 185 | ) 186 | (pin bidirectional line (at 3.81 -7.62 90) (length 5.08) 187 | (name "S" (effects (font (size 1.27 1.27)))) 188 | (number "~" (effects (font (size 1.27 1.27)))) 189 | ) 190 | ) 191 | ) 192 | ) 193 | -------------------------------------------------------------------------------- /kintree/kicad/templates/transistor-pnp.kicad_sym: -------------------------------------------------------------------------------- 1 | (kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor) 2 | (symbol "IPN" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes) 3 | (property "Reference" "Q" (at 0 4.318 0) 4 | (effects (font (size 1.27 1.27))) 5 | ) 6 | (property "Value" "IPN" (at 0 -10.16 0) 7 | (effects (font (size 1.27 1.27)) hide) 8 | ) 9 | (property "Footprint" "Footprint" (at 0 -17.78 0) 10 | (effects (font (size 1.27 1.27)) hide) 11 | ) 12 | (property "Datasheet" "inventree_url" (at 0 -20.32 0) 13 | (effects (font (size 1.27 1.27)) hide) 14 | ) 15 | (property "Manufacturer" "Manufacturer" (at 0 -12.7 0) 16 | (effects (font (size 1.27 1.27)) hide) 17 | ) 18 | (property "Manufacturer Part Number" "MPN" (at 0 -15.24 0) 19 | (effects (font (size 1.27 1.27)) hide) 20 | ) 21 | (property "Part Number" "Value" (at 5.08 3.81 0) 22 | (effects (font (size 1.27 1.27)) (justify left)) 23 | ) 24 | (property "Rated Voltage (Volt)" "Rated Voltage" (at 5.08 1.27 0) 25 | (effects (font (size 1.27 1.27)) (justify left)) 26 | ) 27 | (property "Rated Current (Amps)" "Rated Current" (at 5.08 -1.27 0) 28 | (effects (font (size 1.27 1.27)) (justify left)) 29 | ) 30 | (property "Package Type" "Package Type" (at 5.08 -3.81 0) 31 | (effects (font (size 1.27 1.27)) (justify left)) 32 | ) 33 | (property "ki_keywords" "keywords" (at 0 0 0) 34 | (effects (font (size 1.27 1.27)) hide) 35 | ) 36 | (property "ki_description" "description" (at 0 0 0) 37 | (effects (font (size 1.27 1.27)) hide) 38 | ) 39 | (symbol "IPN_0_1" 40 | (polyline 41 | (pts 42 | (xy 1.27 -2.286) 43 | (xy 1.27 2.286) 44 | ) 45 | (stroke (width 0) (type default)) 46 | (fill (type none)) 47 | ) 48 | (polyline 49 | (pts 50 | (xy 3.81 -2.54) 51 | (xy 1.27 -1.016) 52 | ) 53 | (stroke (width 0) (type default)) 54 | (fill (type none)) 55 | ) 56 | (polyline 57 | (pts 58 | (xy 3.81 2.54) 59 | (xy 1.27 1.016) 60 | ) 61 | (stroke (width 0) (type default)) 62 | (fill (type none)) 63 | ) 64 | (polyline 65 | (pts 66 | (xy 1.397 -1.016) 67 | (xy 2.032 -2.286) 68 | (xy 2.794 -1.143) 69 | (xy 1.397 -1.016) 70 | ) 71 | (stroke (width 0) (type default)) 72 | (fill (type outline)) 73 | ) 74 | ) 75 | (symbol "IPN_1_1" 76 | (pin input line (at -3.81 0 0) (length 5.08) 77 | (name "B" (effects (font (size 1.27 1.27)))) 78 | (number "~" (effects (font (size 1.27 1.27)))) 79 | ) 80 | (pin output line (at 3.81 7.62 270) (length 5.08) 81 | (name "C" (effects (font (size 1.27 1.27)))) 82 | (number "~" (effects (font (size 1.27 1.27)))) 83 | ) 84 | (pin input line (at 3.81 -7.62 90) (length 5.08) 85 | (name "E" (effects (font (size 1.27 1.27)))) 86 | (number "~" (effects (font (size 1.27 1.27)))) 87 | ) 88 | ) 89 | ) 90 | ) 91 | -------------------------------------------------------------------------------- /kintree/kicad/templates_project/templates_project.kicad_pcb: -------------------------------------------------------------------------------- 1 | (kicad_pcb (version 20221018) (generator pcbnew) 2 | 3 | (general 4 | (thickness 1.6) 5 | ) 6 | 7 | (paper "A4") 8 | (layers 9 | (0 "F.Cu" signal) 10 | (31 "B.Cu" signal) 11 | (32 "B.Adhes" user "B.Adhesive") 12 | (33 "F.Adhes" user "F.Adhesive") 13 | (34 "B.Paste" user) 14 | (35 "F.Paste" user) 15 | (36 "B.SilkS" user "B.Silkscreen") 16 | (37 "F.SilkS" user "F.Silkscreen") 17 | (38 "B.Mask" user) 18 | (39 "F.Mask" user) 19 | (40 "Dwgs.User" user "User.Drawings") 20 | (41 "Cmts.User" user "User.Comments") 21 | (42 "Eco1.User" user "User.Eco1") 22 | (43 "Eco2.User" user "User.Eco2") 23 | (44 "Edge.Cuts" user) 24 | (45 "Margin" user) 25 | (46 "B.CrtYd" user "B.Courtyard") 26 | (47 "F.CrtYd" user "F.Courtyard") 27 | (48 "B.Fab" user) 28 | (49 "F.Fab" user) 29 | (50 "User.1" user) 30 | (51 "User.2" user) 31 | (52 "User.3" user) 32 | (53 "User.4" user) 33 | (54 "User.5" user) 34 | (55 "User.6" user) 35 | (56 "User.7" user) 36 | (57 "User.8" user) 37 | (58 "User.9" user) 38 | ) 39 | 40 | (setup 41 | (pad_to_mask_clearance 0) 42 | (pcbplotparams 43 | (layerselection 0x00010fc_ffffffff) 44 | (plot_on_all_layers_selection 0x0000000_00000000) 45 | (disableapertmacros false) 46 | (usegerberextensions false) 47 | (usegerberattributes true) 48 | (usegerberadvancedattributes true) 49 | (creategerberjobfile true) 50 | (dashed_line_dash_ratio 12.000000) 51 | (dashed_line_gap_ratio 3.000000) 52 | (svgprecision 4) 53 | (plotframeref false) 54 | (viasonmask false) 55 | (mode 1) 56 | (useauxorigin false) 57 | (hpglpennumber 1) 58 | (hpglpenspeed 20) 59 | (hpglpendiameter 15.000000) 60 | (dxfpolygonmode true) 61 | (dxfimperialunits true) 62 | (dxfusepcbnewfont true) 63 | (psnegative false) 64 | (psa4output false) 65 | (plotreference true) 66 | (plotvalue true) 67 | (plotinvisibletext false) 68 | (sketchpadsonfab false) 69 | (subtractmaskfromsilk false) 70 | (outputformat 1) 71 | (mirror false) 72 | (drillshape 1) 73 | (scaleselection 1) 74 | (outputdirectory "") 75 | ) 76 | ) 77 | 78 | (net 0 "") 79 | 80 | ) 81 | -------------------------------------------------------------------------------- /kintree/kicad/templates_project/templates_project.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "", 5 | "auto_track_width": true, 6 | "hidden_netclasses": [], 7 | "hidden_nets": [], 8 | "high_contrast_mode": 0, 9 | "net_color_mode": 1, 10 | "opacity": { 11 | "images": 0.6, 12 | "pads": 1.0, 13 | "tracks": 1.0, 14 | "vias": 1.0, 15 | "zones": 0.6 16 | }, 17 | "ratsnest_display_mode": 0, 18 | "selection_filter": { 19 | "dimensions": true, 20 | "footprints": true, 21 | "graphics": true, 22 | "keepouts": true, 23 | "lockedItems": true, 24 | "otherItems": true, 25 | "pads": true, 26 | "text": true, 27 | "tracks": true, 28 | "vias": true, 29 | "zones": true 30 | }, 31 | "visible_items": [ 32 | 0, 33 | 1, 34 | 2, 35 | 3, 36 | 4, 37 | 5, 38 | 8, 39 | 9, 40 | 10, 41 | 11, 42 | 12, 43 | 13, 44 | 14, 45 | 15, 46 | 16, 47 | 17, 48 | 18, 49 | 19, 50 | 20, 51 | 21, 52 | 22, 53 | 23, 54 | 24, 55 | 25, 56 | 26, 57 | 27, 58 | 28, 59 | 29, 60 | 30, 61 | 32, 62 | 33, 63 | 34, 64 | 35, 65 | 36 66 | ], 67 | "visible_layers": "fffffff_ffffffff", 68 | "zone_display_mode": 0 69 | }, 70 | "meta": { 71 | "filename": "templates_project.kicad_prl", 72 | "version": 3 73 | }, 74 | "project": { 75 | "files": [] 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /kintree/kicad/templates_project/templates_project.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "board_outline_line_width": 0.1, 7 | "copper_line_width": 0.2, 8 | "copper_text_size_h": 1.5, 9 | "copper_text_size_v": 1.5, 10 | "copper_text_thickness": 0.3, 11 | "other_line_width": 0.15, 12 | "silk_line_width": 0.15, 13 | "silk_text_size_h": 1.0, 14 | "silk_text_size_v": 1.0, 15 | "silk_text_thickness": 0.15 16 | }, 17 | "diff_pair_dimensions": [], 18 | "drc_exclusions": [], 19 | "rules": { 20 | "solder_mask_clearance": 0.0, 21 | "solder_mask_min_width": 0.0 22 | }, 23 | "track_widths": [], 24 | "via_dimensions": [] 25 | }, 26 | "layer_presets": [], 27 | "viewports": [] 28 | }, 29 | "boards": [], 30 | "cvpcb": { 31 | "equivalence_files": [] 32 | }, 33 | "erc": { 34 | "erc_exclusions": [], 35 | "meta": { 36 | "version": 0 37 | }, 38 | "pin_map": [ 39 | [ 40 | 0, 41 | 0, 42 | 0, 43 | 0, 44 | 0, 45 | 0, 46 | 1, 47 | 0, 48 | 0, 49 | 0, 50 | 0, 51 | 2 52 | ], 53 | [ 54 | 0, 55 | 2, 56 | 0, 57 | 1, 58 | 0, 59 | 0, 60 | 1, 61 | 0, 62 | 2, 63 | 2, 64 | 2, 65 | 2 66 | ], 67 | [ 68 | 0, 69 | 0, 70 | 0, 71 | 0, 72 | 0, 73 | 0, 74 | 1, 75 | 0, 76 | 1, 77 | 0, 78 | 1, 79 | 2 80 | ], 81 | [ 82 | 0, 83 | 1, 84 | 0, 85 | 0, 86 | 0, 87 | 0, 88 | 1, 89 | 1, 90 | 2, 91 | 1, 92 | 1, 93 | 2 94 | ], 95 | [ 96 | 0, 97 | 0, 98 | 0, 99 | 0, 100 | 0, 101 | 0, 102 | 1, 103 | 0, 104 | 0, 105 | 0, 106 | 0, 107 | 2 108 | ], 109 | [ 110 | 0, 111 | 0, 112 | 0, 113 | 0, 114 | 0, 115 | 0, 116 | 0, 117 | 0, 118 | 0, 119 | 0, 120 | 0, 121 | 2 122 | ], 123 | [ 124 | 1, 125 | 1, 126 | 1, 127 | 1, 128 | 1, 129 | 0, 130 | 1, 131 | 1, 132 | 1, 133 | 1, 134 | 1, 135 | 2 136 | ], 137 | [ 138 | 0, 139 | 0, 140 | 0, 141 | 1, 142 | 0, 143 | 0, 144 | 1, 145 | 0, 146 | 0, 147 | 0, 148 | 0, 149 | 2 150 | ], 151 | [ 152 | 0, 153 | 2, 154 | 1, 155 | 2, 156 | 0, 157 | 0, 158 | 1, 159 | 0, 160 | 2, 161 | 2, 162 | 2, 163 | 2 164 | ], 165 | [ 166 | 0, 167 | 2, 168 | 0, 169 | 1, 170 | 0, 171 | 0, 172 | 1, 173 | 0, 174 | 2, 175 | 0, 176 | 0, 177 | 2 178 | ], 179 | [ 180 | 0, 181 | 2, 182 | 1, 183 | 1, 184 | 0, 185 | 0, 186 | 1, 187 | 0, 188 | 2, 189 | 0, 190 | 0, 191 | 2 192 | ], 193 | [ 194 | 2, 195 | 2, 196 | 2, 197 | 2, 198 | 2, 199 | 2, 200 | 2, 201 | 2, 202 | 2, 203 | 2, 204 | 2, 205 | 2 206 | ] 207 | ], 208 | "rule_severities": { 209 | "bus_definition_conflict": "error", 210 | "bus_entry_needed": "error", 211 | "bus_to_bus_conflict": "error", 212 | "bus_to_net_conflict": "error", 213 | "conflicting_netclasses": "error", 214 | "different_unit_footprint": "error", 215 | "different_unit_net": "error", 216 | "duplicate_reference": "error", 217 | "duplicate_sheet_names": "error", 218 | "endpoint_off_grid": "warning", 219 | "extra_units": "error", 220 | "global_label_dangling": "warning", 221 | "hier_label_mismatch": "error", 222 | "label_dangling": "error", 223 | "lib_symbol_issues": "warning", 224 | "missing_bidi_pin": "warning", 225 | "missing_input_pin": "warning", 226 | "missing_power_pin": "error", 227 | "missing_unit": "warning", 228 | "multiple_net_names": "warning", 229 | "net_not_bus_member": "warning", 230 | "no_connect_connected": "warning", 231 | "no_connect_dangling": "warning", 232 | "pin_not_connected": "error", 233 | "pin_not_driven": "error", 234 | "pin_to_pin": "warning", 235 | "power_pin_not_driven": "error", 236 | "similar_labels": "warning", 237 | "simulation_model_issue": "error", 238 | "unannotated": "error", 239 | "unit_value_mismatch": "error", 240 | "unresolved_variable": "error", 241 | "wire_dangling": "error" 242 | } 243 | }, 244 | "libraries": { 245 | "pinned_footprint_libs": [], 246 | "pinned_symbol_libs": [] 247 | }, 248 | "meta": { 249 | "filename": "templates_project.kicad_pro", 250 | "version": 1 251 | }, 252 | "net_settings": { 253 | "classes": [ 254 | { 255 | "bus_width": 12, 256 | "clearance": 0.2, 257 | "diff_pair_gap": 0.25, 258 | "diff_pair_via_gap": 0.25, 259 | "diff_pair_width": 0.2, 260 | "line_style": 0, 261 | "microvia_diameter": 0.3, 262 | "microvia_drill": 0.1, 263 | "name": "Default", 264 | "pcb_color": "rgba(0, 0, 0, 0.000)", 265 | "schematic_color": "rgba(0, 0, 0, 0.000)", 266 | "track_width": 0.25, 267 | "via_diameter": 0.8, 268 | "via_drill": 0.4, 269 | "wire_width": 6 270 | } 271 | ], 272 | "meta": { 273 | "version": 3 274 | }, 275 | "net_colors": null, 276 | "netclass_assignments": null, 277 | "netclass_patterns": [] 278 | }, 279 | "pcbnew": { 280 | "last_paths": { 281 | "gencad": "", 282 | "idf": "", 283 | "netlist": "", 284 | "specctra_dsn": "", 285 | "step": "", 286 | "vrml": "" 287 | }, 288 | "page_layout_descr_file": "" 289 | }, 290 | "schematic": { 291 | "annotate_start_num": 0, 292 | "drawing": { 293 | "dashed_lines_dash_length_ratio": 12.0, 294 | "dashed_lines_gap_length_ratio": 3.0, 295 | "default_line_thickness": 6.0, 296 | "default_text_size": 50.0, 297 | "field_names": [], 298 | "intersheets_ref_own_page": false, 299 | "intersheets_ref_prefix": "", 300 | "intersheets_ref_short": false, 301 | "intersheets_ref_show": false, 302 | "intersheets_ref_suffix": "", 303 | "junction_size_choice": 3, 304 | "label_size_ratio": 0.25, 305 | "pin_symbol_size": 25.0, 306 | "text_offset_ratio": 0.08 307 | }, 308 | "legacy_lib_dir": "", 309 | "legacy_lib_list": [], 310 | "meta": { 311 | "version": 1 312 | }, 313 | "net_format_name": "", 314 | "page_layout_descr_file": "", 315 | "plot_directory": "", 316 | "spice_current_sheet_as_root": false, 317 | "spice_external_command": "spice \"%I\"", 318 | "spice_model_current_sheet_as_root": true, 319 | "spice_save_all_currents": false, 320 | "spice_save_all_voltages": false, 321 | "subpart_first_id": 65, 322 | "subpart_id_separator": 0 323 | }, 324 | "sheets": [ 325 | [ 326 | "b588025f-8c23-406b-a049-ad8593913ab0", 327 | "" 328 | ] 329 | ], 330 | "text_variables": {} 331 | } 332 | -------------------------------------------------------------------------------- /kintree/kicad/templates_project/templates_project.kicad_sch: -------------------------------------------------------------------------------- 1 | (kicad_sch (version 20230121) (generator eeschema) 2 | 3 | (uuid b588025f-8c23-406b-a049-ad8593913ab0) 4 | 5 | (paper "A4") 6 | 7 | (lib_symbols 8 | ) 9 | 10 | 11 | (sheet_instances 12 | (path "/" (page "1")) 13 | ) 14 | ) 15 | -------------------------------------------------------------------------------- /kintree/kintree_gui.py: -------------------------------------------------------------------------------- 1 | import flet as ft 2 | 3 | from .gui.gui import kintree_gui 4 | 5 | 6 | def main(view='flet_app'): 7 | if view == 'browser': 8 | ft.app(target=kintree_gui, view=ft.AppView.WEB_BROWSER) 9 | return 10 | ft.app(target=kintree_gui, view=ft.AppView.FLET_APP) 11 | -------------------------------------------------------------------------------- /kintree/search/automationdirect_api.py: -------------------------------------------------------------------------------- 1 | from ..common.tools import download 2 | 3 | # These are the 'keys' we want to pull out response 4 | SEARCH_HEADERS = [ 5 | 'item_code', # name 6 | 'primary_desc', # description 7 | 'revision', # revision 8 | 'keywords', # keywords 9 | 'item_code', # suppli er_part_number 10 | 'manufacturer_name', # manufacturer_name 11 | 'item_code', # manufacturer_part_number 12 | 'url_fullpath', # supplier_link 13 | 'spec_url', # datasheet 14 | 'image_file_name', # image 15 | 16 | 'insert_url', # insert PD 17 | 'orderable_flg', 18 | 'prod_status', 19 | 'price', 20 | 'manual_url', # not full path to html page, value is filename.html 21 | 'unit_of_measure', 22 | 'leadtime_cd', 23 | 'production_time', 24 | 'warranty', 25 | ] 26 | 27 | PARAMETERS_MAP = [ 28 | 'tech_attributes', # List of parameters, not list of dictionaries, changes based on product returned 29 | ] 30 | 31 | PRICING_MAP = [ 32 | 'ordering_attributes', # List, e.g. ['Is Cut To Length: True', 'Maximum Cut Length: 2500', 'Minimum Cut Length: 25'] 33 | 'price', # Automation Direct only has one price, no price breaks 34 | 'unit_of_measure', # e.g. 'FT' 35 | ] 36 | 37 | 38 | def get_default_search_keys(): 39 | return [ 40 | # Order matters 41 | 'item_code', # name 42 | 'primary_desc', # description 43 | 'revision', # revision 44 | 'keywords', # keywords 45 | 'item_code', # supplier_part_number 46 | 'manufacturer_name', # manufacturer_name 47 | 'item_code', # manufacturer_part_number 48 | 'url_fullpath', # supplier_link 49 | 'spec_url', # datasheet 50 | 'image_file_name', # image 51 | ] 52 | 53 | 54 | def find_categories(part_details: str): 55 | ''' Find categories ''' 56 | try: 57 | return part_details['parentCatalogName'], part_details['catalogName'] 58 | except: 59 | return None, None 60 | 61 | 62 | def fetch_part_info(part_number: str, silent=False) -> dict: 63 | ''' Fetch part data from API ''' 64 | 65 | # Load Automation Direct settingss 66 | import re 67 | from ..common.tools import cprint 68 | from ..config import settings, config_interface 69 | automationdirect_api_settings = config_interface.load_file(settings.CONFIG_AUTOMATIONDIRECT_API) 70 | 71 | part_info = {} 72 | 73 | def search_timeout(timeout=10): 74 | url = automationdirect_api_settings.get('AUTOMATIONDIRECT_API_URL', '') + automationdirect_api_settings.get('AUTOMATIONDIRECT_API_SEARCH_QUERY', '') + part_number + automationdirect_api_settings.get('AUTOMATIONDIRECT_API_SEARCH_STRING', '') + part_number 75 | response = download(url, timeout=timeout) 76 | return response 77 | 78 | # Query part number 79 | try: 80 | part = search_timeout() 81 | part = part['solrResult']['response'] # extract the data for parts returned 82 | if part['numFound'] > 0: 83 | if part['numFound'] == 1: 84 | cprint(f'[INFO]\tFound exactly one result for "{part_number}"', silent=True) 85 | else: 86 | cprint(f'[INFO]\tFound {part["numFound"]} results for "{part_number}", selecting first result', silent=False) 87 | part = part['docs'][0] # choose the first part in the returned returned list 88 | else: 89 | part = None 90 | except Exception as e: 91 | cprint(f'[INFO]\tError: fetch_part_info(): {repr(e)}') 92 | part = None 93 | 94 | if not part: 95 | return part_info 96 | 97 | category, subcategory = find_categories(part) 98 | try: 99 | part_info['category'] = category 100 | part_info['subcategory'] = subcategory 101 | except: 102 | part_info['category'] = '' 103 | part_info['subcategory'] = '' 104 | 105 | headers = SEARCH_HEADERS # keys we want to search for 106 | 107 | # Get all returned data we want 108 | for key in part: 109 | if key in headers: 110 | if key == 'image_file_name': # JSON only returns image name, need to add path 111 | try: 112 | part_info[key] = automationdirect_api_settings.get('AUTOMATIONDIRECT_API_IMAGE_PATH', '') + part['image_file_name'] 113 | except IndexError: 114 | pass 115 | elif key == 'spec_url': # datasheet url returns partial path, need to add ROOT URL 116 | try: 117 | part_info[key] = automationdirect_api_settings.get('AUTOMATIONDIRECT_API_ROOT_URL', '') + part['spec_url'] 118 | except IndexError: 119 | pass 120 | elif key == 'insert_url': # insert url returns partial path, need to add ROOT URL 121 | try: 122 | part_info[key] = automationdirect_api_settings.get('AUTOMATIONDIRECT_API_ROOT_URL', '') + part['insert_url'] 123 | except IndexError: 124 | pass 125 | elif key == 'manual_url': # manul url returns .html file name, need to build the rest of the URL 126 | try: 127 | part_info[key] = automationdirect_api_settings.get('AUTOMATIONDIRECT_API_ROOT_URL', '') + '/static/manuals/' + str(part['manual_url']).rsplit('.', 1)[0] + '/' + part['manual_url'] 128 | except IndexError: 129 | pass 130 | elif key == 'url_fullpath': # despite being named fullpath, the URL needs the TLD as a prefix 131 | try: 132 | part_info[key] = automationdirect_api_settings.get('AUTOMATIONDIRECT_API_ROOT_URL', '') + '/adc/shopping' + str(part['url_fullpath']) 133 | except IndexError: 134 | pass 135 | elif key == 'manufacturer_name': # taken care of in parameter list below 136 | pass 137 | else: 138 | part_info[key] = part[key] 139 | 140 | # Parameters 141 | part_info['parameters'] = {} 142 | [parameter_key] = PARAMETERS_MAP 143 | 144 | if part.get(parameter_key, ''): 145 | for attribute in part[parameter_key]: 146 | attribute_list = [x.strip() for x in attribute.split(':')] 147 | parameter_name = attribute_list[0] 148 | parameter_name = parameter_name.replace('/', '') 149 | parameter_value = attribute_list[1] 150 | try: 151 | html_li_list = re.split(r"]*\s*>|(\&(?:[\w\d]+|#\d+|#x[a-f\d]+);)", parameter_value) 152 | cleaned_html_li_list = list(filter(None, html_li_list)) 153 | parameter_value = ', '.join(cleaned_html_li_list) 154 | except Exception as e: 155 | print(f'{repr(e)}') 156 | if parameter_name == "Brand": # Manufacturer Name returned as a parameter, pick it out of parameters list aand store it appropriately 157 | part_info['manufacturer_name'] = parameter_value 158 | # Nominal Input Voltage gives range min-max, parse it out to put in min/max params 159 | if parameter_name == "Nominal Input Voltage": 160 | if parameter_value.count('-') == 1: 161 | parameter_value = re.sub(r'[^\d-]+', '', parameter_value) 162 | values_list = parameter_value.split('-') 163 | min_value = min(values_list) 164 | max_value = max(values_list) 165 | part_info['parameters']['Min Input Voltage'] = min_value 166 | part_info['parameters']['Max Input Voltage'] = max_value 167 | else: 168 | # more than one range, copy into set param fields 169 | part_info['parameters']['Min Input Voltage'] = parameter_value 170 | part_info['parameters']['Max Input Voltage'] = parameter_value 171 | # Nominal Output Voltage gives range min-max, parse it out to put in min/max params 172 | if parameter_name == "Nominal Output Voltage": 173 | if parameter_value.count('-') == 1: 174 | parameter_value = re.sub(r'[^\d-]+', '', parameter_value) 175 | values_list = parameter_value.split('-') 176 | min_value = min(values_list) 177 | max_value = max(values_list) 178 | part_info['parameters']['Min Output Voltage'] = min_value 179 | part_info['parameters']['Max Output Voltage'] = max_value 180 | else: 181 | # more than one range, copy into set param fields 182 | part_info['parameters']['Min Output Voltage'] = parameter_value 183 | part_info['parameters']['Max Output Voltage'] = parameter_value 184 | else: 185 | # Append to parameters dictionary 186 | part_info['parameters'][parameter_name] = parameter_value 187 | 188 | # Pricing 189 | part_info['pricing'] = {} 190 | [ordering_attributes, price_key, unit_per_price] = PRICING_MAP 191 | 192 | # Parse out ordering attributes 193 | pricing_attributes = {} 194 | price_per_unit = part.get(price_key, '0') 195 | try: 196 | for attribute in part[ordering_attributes]: 197 | attribute = attribute.split(':') 198 | attribute = [x.strip() for x in attribute] 199 | pricing_attributes[str(attribute[0])] = attribute[1] 200 | 201 | min_quantity = int(pricing_attributes['Minimum Cut Length']) 202 | max_quanitity = int(pricing_attributes['Maximum Cut Length']) 203 | 204 | price_per_unit = part[price_key] 205 | 206 | # Automation Direct doesn't have price breaks, but we can create common set quanitities for reference 207 | quantities = [100, 250, 500, 1000, 1500, 2000, 2500, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000, 15000] 208 | quantities.insert(0, min_quantity) 209 | quantities.append(max_quanitity) 210 | quantities.sort() 211 | quantities = [qty for qty in quantities if qty <= max_quanitity] 212 | for i in range(len(quantities) - 1): 213 | part_info['pricing'][quantities[i]] = price_per_unit 214 | 215 | except KeyError as e: 216 | from ..common.tools import cprint 217 | cprint(f'[INFO]\tNo pricing attribute "{e.args[0]}" found for "{part_number}"', silent=silent) 218 | part_info['pricing']['1'] = price_per_unit 219 | 220 | part_info['currency'] = 'USD' 221 | 222 | # Extra search fields 223 | if settings.CONFIG_AUTOMATIONDIRECT.get('EXTRA_FIELDS', None): 224 | for extra_field in settings.CONFIG_AUTOMATIONDIRECT['EXTRA_FIELDS']: 225 | if part.get(extra_field, None): 226 | part_info['parameters'][extra_field] = part[extra_field] 227 | else: 228 | from ..common.tools import cprint 229 | cprint(f'[INFO]\tWarning: Extra field "{extra_field}" not found in search results', silent=False) 230 | 231 | return part_info 232 | 233 | 234 | def test_api() -> bool: 235 | ''' Test method for API ''' 236 | 237 | test_success = True 238 | expected = { 239 | 'image_file_name': 'https://cdn.automationdirect.com/images/products/medium/m_bx16nd3.jpg', 240 | 'item_code': 'BX-16ND3', 241 | 'manual_url': 'https://www.automationdirect.com/static/manuals/brxuserm/brxuserm.html', 242 | 'unit_of_measure': 'EA', 243 | "parameters": 244 | { 245 | 'Brand': 'BRX', 246 | 'Item': 'Input module', 247 | 'IO Module Type': 'Discrete', 248 | 'Number of Input Points': '16', 249 | 'Min Input Voltage': '12', 250 | 'Max Input Voltage': '24', 251 | 'Nominal Input Voltage': '12-24', 252 | 'Discrete Input Type': 'Sinking/sourcing', 253 | 'Fast Response': 'No', 'Number of Isolated Input Commons': '4', 254 | 'Number of Points per Common': '4', 255 | 'Requires': 'BX-RTB10, BX-RTB10-1 or BX-RTB10-2 terminal block kit or ZIPLink pre-wired cables', 256 | 'Programming Software': 'Do-more Designer programming software v2.0 or later' 257 | } 258 | } 259 | 260 | test_part = fetch_part_info('BX-16ND3', silent=True) 261 | if not test_part: 262 | test_success = False 263 | 264 | # Check content of response 265 | if test_success: 266 | for key, value in expected.items(): 267 | if test_part[key] != value: 268 | print(f'"{test_part[key]}" <> "{value}"') 269 | test_success = False 270 | break 271 | 272 | return test_success 273 | -------------------------------------------------------------------------------- /kintree/search/digikey_api.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import digikey 4 | 5 | from ..config import settings, config_interface 6 | 7 | SEARCH_HEADERS = [ 8 | 'description', 9 | 'digi_key_part_number', 10 | 'manufacturer', 11 | 'manufacturer_product_number', 12 | 'product_url', 13 | 'datasheet_url', 14 | 'photo_url', 15 | ] 16 | PARAMETERS_MAP = [ 17 | 'parameters', 18 | 'parameter_text', 19 | 'value_text', 20 | ] 21 | 22 | PRICING_MAP = [ 23 | 'product_variations', 24 | 'digi_key_product_number', 25 | 'standard_pricing', 26 | 'break_quantity', 27 | 'unit_price', 28 | 'package_type' 29 | ] 30 | 31 | os.environ['DIGIKEY_STORAGE_PATH'] = settings.DIGIKEY_STORAGE_PATH 32 | # Check if storage path exists, else create it 33 | if not os.path.exists(os.environ['DIGIKEY_STORAGE_PATH']): 34 | os.makedirs(os.environ['DIGIKEY_STORAGE_PATH'], exist_ok=True) 35 | 36 | 37 | def disable_api_logger(): 38 | # Digi-Key API logger 39 | logging.getLogger('digikey.v3.api').setLevel(logging.CRITICAL) 40 | # Disable DEBUG 41 | logging.disable(logging.DEBUG) 42 | 43 | 44 | def check_environment() -> bool: 45 | DIGIKEY_CLIENT_ID = os.environ.get('DIGIKEY_CLIENT_ID', None) 46 | DIGIKEY_CLIENT_SECRET = os.environ.get('DIGIKEY_CLIENT_SECRET', None) 47 | 48 | if not DIGIKEY_CLIENT_ID or not DIGIKEY_CLIENT_SECRET: 49 | return False 50 | 51 | return True 52 | 53 | 54 | def setup_environment(force=False) -> bool: 55 | if not check_environment() or force: 56 | # SETUP the Digikey authentication see https://developer.digikey.com/documentation/organization#production 57 | digikey_api_settings = config_interface.load_file(settings.CONFIG_DIGIKEY_API) 58 | os.environ['DIGIKEY_CLIENT_ID'] = digikey_api_settings['DIGIKEY_CLIENT_ID'] 59 | os.environ['DIGIKEY_CLIENT_SECRET'] = digikey_api_settings['DIGIKEY_CLIENT_SECRET'] 60 | os.environ['DIGIKEY_LOCAL_SITE'] = digikey_api_settings.get('DIGIKEY_LOCAL_SITE', 'US') 61 | os.environ['DIGIKEY_LOCAL_LANGUAGE'] = digikey_api_settings.get('DIGIKEY_LOCAL_LANGUAGE', 'en') 62 | os.environ['DIGIKEY_LOCAL_CURRENCY'] = digikey_api_settings.get('DIGIKEY_LOCAL_CURRENCY', 'USD') 63 | return check_environment() 64 | 65 | 66 | def get_default_search_keys(): 67 | return [ 68 | 'product_description', 69 | 'product_description', 70 | 'revision', 71 | 'keywords', 72 | 'digi_key_part_number', 73 | 'manufacturer', 74 | 'manufacturer_product_number', 75 | 'product_url', 76 | 'datasheet_url', 77 | 'photo_url', 78 | ] 79 | 80 | 81 | def find_categories(part_details: str): 82 | ''' Find categories ''' 83 | category = part_details.get('category') 84 | subcategory = None 85 | if category: 86 | subcategory = category.get('child_categories')[0] 87 | category = category.get('name') 88 | if subcategory: 89 | subcategory = subcategory.get('name') 90 | return category, subcategory 91 | 92 | 93 | def fetch_part_info(part_number: str) -> dict: 94 | ''' Fetch part data from API ''' 95 | from wrapt_timeout_decorator import timeout 96 | 97 | part_info = {} 98 | if not setup_environment(): 99 | from ..common.tools import cprint 100 | cprint('[INFO]\tWarning: DigiKey API settings are not configured') 101 | return part_info 102 | 103 | # THIS METHOD CAN SOMETIMES RETURN INCORRECT MATCH 104 | # Added logic to check the result in the GUI flow 105 | @timeout(dec_timeout=20) 106 | def digikey_search_timeout(): 107 | return digikey.product_details( 108 | part_number, 109 | x_digikey_locale_site=os.environ['DIGIKEY_LOCAL_SITE'], 110 | x_digikey_locale_language=os.environ['DIGIKEY_LOCAL_LANGUAGE'], 111 | x_digikey_locale_currency=os.environ['DIGIKEY_LOCAL_CURRENCY'], 112 | ).to_dict() 113 | 114 | # Method to process price breaks 115 | def process_price_break(product_variation): 116 | part_info['digi_key_part_number'] = product_variation.get(digi_number_key) 117 | for price_break in product_variation[pricing_key]: 118 | quantity = price_break[qty_key] 119 | price = price_break[price_key] 120 | part_info['pricing'][quantity] = price 121 | 122 | # Query part number 123 | try: 124 | part = digikey_search_timeout() 125 | except: 126 | part = None 127 | 128 | if not part: 129 | return part_info 130 | if 'product' not in part or not part['product']: 131 | return part_info 132 | 133 | part_info['currency'] = part['search_locale_used']['currency'] 134 | part = part['product'] 135 | 136 | category, subcategory = find_categories(part) 137 | try: 138 | part_info['category'] = category 139 | part_info['subcategory'] = subcategory 140 | except: 141 | part_info['category'] = '' 142 | part_info['subcategory'] = '' 143 | 144 | headers = SEARCH_HEADERS 145 | 146 | for key in part: 147 | if key in headers: 148 | if key == 'manufacturer': 149 | part_info[key] = part['manufacturer'].get('name') 150 | elif key == 'description': 151 | part_info['product_description'] = part['description'].get('product_description') 152 | part_info['detailed_description'] = part['description'].get('detailed_description') 153 | else: 154 | part_info[key] = part[key] 155 | 156 | # Parameters 157 | part_info['parameters'] = {} 158 | [parameter_key, name_key, value_key] = PARAMETERS_MAP 159 | 160 | for parameter in part[parameter_key]: 161 | parameter_name = parameter.get(name_key, '') 162 | parameter_value = parameter.get(value_key, '') 163 | # Append to parameters dictionary 164 | part_info['parameters'][parameter_name] = parameter_value 165 | # process classifications as parameters 166 | for classification, value in part.get('classifications', {}).items(): 167 | part_info['parameters'][classification] = value 168 | 169 | # Pricing 170 | part_info['pricing'] = {} 171 | [variations_key, 172 | digi_number_key, 173 | pricing_key, 174 | qty_key, 175 | price_key, 176 | package_key] = PRICING_MAP 177 | 178 | variations = part[variations_key] 179 | if len(variations) == 1: 180 | process_price_break(variations[0]) 181 | else: 182 | for variation in variations: 183 | # we try to get the not TR or Digi-Reel option 184 | package_type = variation.get(package_key).get('id') 185 | if all(package_type != x for x in [1, 243]): 186 | process_price_break(variation) 187 | break 188 | # if no other option was found use the first one returned 189 | if not part_info['pricing'] and variations: 190 | process_price_break(variations[0]) 191 | 192 | # Extra search fields 193 | if settings.CONFIG_DIGIKEY.get('EXTRA_FIELDS'): 194 | for extra_field in settings.CONFIG_DIGIKEY['EXTRA_FIELDS']: 195 | if part.get(extra_field): 196 | part_info['parameters'][extra_field] = part[extra_field] 197 | else: 198 | from ..common.tools import cprint 199 | cprint(f'[INFO]\tWarning: Extra field "{extra_field}" not found in search results', silent=False) 200 | 201 | return part_info 202 | 203 | 204 | def test_api(check_content=False) -> bool: 205 | ''' Test method for API token ''' 206 | test_success = True 207 | expected = { 208 | 'product_description': 'RES 10K OHM 5% 1/16W 0402', 209 | 'digi_key_part_number': 'RMCF0402JT10K0CT-ND', 210 | 'manufacturer': 'Stackpole Electronics Inc', 211 | 'manufacturer_product_number': 'RMCF0402JT10K0', 212 | 'product_url': 'https://www.digikey.com/en/products/detail/stackpole-electronics-inc/RMCF0402JT10K0/1758206', 213 | 'datasheet_url': 'https://www.seielect.com/catalog/sei-rmcf_rmcp.pdf', 214 | 'photo_url': 'https://mm.digikey.com/Volume0/opasdata/d220001/medias/images/2597/MFG_RMC SERIES.jpg', 215 | } 216 | 217 | test_part = fetch_part_info('RMCF0402JT10K0') 218 | 219 | # Check for response 220 | if not test_part: 221 | test_success = False 222 | 223 | if not check_content: 224 | return test_success 225 | 226 | # Check content of response 227 | if test_success: 228 | for key, value in expected.items(): 229 | if test_part[key] != value: 230 | print(f'{test_part[key]} != {value}') 231 | test_success = False 232 | break 233 | 234 | return test_success 235 | -------------------------------------------------------------------------------- /kintree/search/jameco_api.py: -------------------------------------------------------------------------------- 1 | import html 2 | import re 3 | from ..common.tools import download 4 | 5 | SEARCH_HEADERS = [ 6 | 'title', 7 | 'name', 8 | 'prod_id', 9 | 'ss_attr_manufacturer', 10 | 'manufacturer_part_number', 11 | 'url', 12 | 'imageUrl', 13 | 'related_prod_id', 14 | 'category', 15 | ] 16 | 17 | # Not really a map for Jameco. 18 | # Parameters are listed at same level as the search keys, not in separate list 19 | PARAMETERS_KEYS = [ 20 | 'product_type_unigram', 21 | 'ss_attr_voltage_rating', 22 | 'ss_attr_multiple_order_quantity', 23 | ] 24 | 25 | 26 | def get_default_search_keys(): 27 | # order matters, linked with part_form[] order in inventree_interface.translate_supplier_to_form() 28 | return [ 29 | 'title', 30 | 'name', 31 | 'revision', 32 | 'keywords', 33 | 'prod_id', 34 | 'ss_attr_manufacturer', 35 | 'manufacturer_part_number', 36 | 'url', 37 | 'datasheet', 38 | 'imageUrl', 39 | ] 40 | 41 | 42 | def find_categories(part_details: str): 43 | ''' Find categories ''' 44 | try: 45 | return part_details['parentCatalogName'], part_details['catalogName'] 46 | except: 47 | return None, None 48 | 49 | 50 | def fetch_part_info(part_number: str) -> dict: 51 | ''' Fetch part data from API ''' 52 | 53 | # Load Jameco settings 54 | from ..config import settings, config_interface 55 | jameco_api_settings = config_interface.load_file(settings.CONFIG_JAMECO_API) 56 | 57 | part_info = {} 58 | 59 | def search_timeout(timeout=10): 60 | url = jameco_api_settings.get('JAMECO_API_URL', '') + part_number 61 | response = download(url, timeout=timeout) 62 | return response 63 | 64 | # Query part number 65 | try: 66 | part = search_timeout() 67 | # Extract results, select first in returned search List 68 | part = part.get('results', None) 69 | part = part[0] 70 | except: 71 | part = None 72 | 73 | if not part: 74 | return part_info 75 | 76 | category, subcategory = find_categories(part) 77 | try: 78 | part_info['category'] = category 79 | part_info['subcategory'] = subcategory 80 | except: 81 | part_info['category'] = '' 82 | part_info['subcategory'] = '' 83 | 84 | headers = SEARCH_HEADERS 85 | 86 | for key in part: 87 | if key in headers: 88 | if key == 'imageUrl': 89 | try: 90 | part_info[key] = part['imageUrl'] 91 | except IndexError: 92 | pass 93 | elif key in ['title', 'name', 'category']: 94 | # Jameco title/name is often >100 chars, which causes an error later. Check for it here. 95 | if (len(part[key]) > 100): 96 | trimmed_value = str(part[key])[:100] 97 | part_info[key] = html.unescape(trimmed_value) # Json data sometimes has HTML encoded chars, e.g. " 98 | else: 99 | part_info[key] = html.unescape(part[key]) 100 | else: 101 | part_info[key] = part[key] 102 | 103 | # Parameters 104 | part_info['parameters'] = {} 105 | 106 | for i, parameter_key in enumerate(PARAMETERS_KEYS): 107 | if part.get(parameter_key, ''): 108 | parameter_name = parameter_key 109 | parameter_value = part[parameter_key] 110 | if isinstance(parameter_value, list): 111 | parameter_string = ', '.join(parameter_value) 112 | part_info['parameters'][parameter_name] = parameter_string 113 | else: 114 | # Append to parameters dictionary 115 | part_info['parameters'][parameter_name] = parameter_value 116 | 117 | # Pricing 118 | part_info['pricing'] = {} 119 | 120 | # Jameco returns price breaks as a string of HTML text 121 | # Convert pricing string pattern to List, then dictionary for Ki-nTree 122 | price_break_str = part['secondary_prices'] 123 | price_break_str = price_break_str.replace(',', '') # remove comma 124 | price_break_str = re.sub(r'(\<br\s\/&*gt)', '', price_break_str) # remove HTML 125 | price_break_str = re.sub(';', ':', price_break_str) # remove ; char 126 | price_break_str = re.sub(r'(\:\s+\$)|\;', ':', price_break_str) # remove $ char 127 | price_break_list = price_break_str.split(':') # split on : 128 | price_break_list.pop() # remove last empty element in List 129 | 130 | for i in range(0, len(price_break_list), 2): 131 | quantity = int(price_break_list[i]) 132 | price = float(price_break_list[i + 1]) 133 | part_info['pricing'][quantity] = price 134 | 135 | part_info['currency'] = 'USD' 136 | 137 | # Extra search fields 138 | if settings.CONFIG_JAMECO.get('EXTRA_FIELDS', None): 139 | for extra_field in settings.CONFIG_JAMECO['EXTRA_FIELDS']: 140 | if part.get(extra_field, None): 141 | part_info['parameters'][extra_field] = part[extra_field] 142 | else: 143 | from ..common.tools import cprint 144 | cprint(f'[INFO]\tWarning: Extra field "{extra_field}" not found in search results', silent=False) 145 | 146 | return part_info 147 | 148 | 149 | def test_api() -> bool: 150 | ''' Test method for API ''' 151 | 152 | test_success = True 153 | 154 | expected = { 155 | 'manufacturer_part_number': 'PN2222ABU', 156 | 'name': 'Transistor PN2222A NPN Silicon General Purpose TO-92', 157 | 'prod_id': '178511', 158 | } 159 | 160 | test_part = fetch_part_info('178511') 161 | if not test_part: 162 | test_success = False 163 | 164 | # Check content of response 165 | if test_success: 166 | for key, value in expected.items(): 167 | if test_part[key] != value: 168 | print(f'"{test_part[key]}" <> "{value}"') 169 | test_success = False 170 | break 171 | 172 | return test_success 173 | -------------------------------------------------------------------------------- /kintree/search/lcsc_api.py: -------------------------------------------------------------------------------- 1 | from ..common.tools import download 2 | 3 | SEARCH_HEADERS = [ 4 | 'productDescEn', 5 | 'productIntroEn', 6 | 'productCode', 7 | 'brandNameEn', 8 | 'productModel', 9 | 'pdfUrl', 10 | 'productImages', 11 | ] 12 | PARAMETERS_MAP = [ 13 | 'paramVOList', 14 | 'paramNameEn', 15 | 'paramValueEn', 16 | ] 17 | 18 | PRICING_MAP = [ 19 | 'productPriceList', 20 | 'ladder', 21 | 'usdPrice', 22 | ] 23 | 24 | 25 | def get_default_search_keys(): 26 | return [ 27 | 'productIntroEn', 28 | 'productIntroEn', 29 | 'revision', 30 | 'keywords', 31 | 'productCode', 32 | 'brandNameEn', 33 | 'productModel', 34 | 'part_url', 35 | 'pdfUrl', 36 | 'productImages', 37 | ] 38 | 39 | 40 | def find_categories(part_details: str): 41 | ''' Find categories ''' 42 | try: 43 | return part_details['parentCatalogName'], part_details['catalogName'] 44 | except: 45 | return None, None 46 | 47 | 48 | def fetch_part_info(part_number: str) -> dict: 49 | ''' Fetch part data from API ''' 50 | 51 | # Load LCSC settings 52 | from ..config import settings, config_interface 53 | lcsc_api_settings = config_interface.load_file(settings.CONFIG_LCSC_API) 54 | 55 | part_info = {} 56 | 57 | def search_timeout(timeout=10): 58 | url = lcsc_api_settings.get('LCSC_API_URL', '') + part_number 59 | response = download(url, timeout=timeout) 60 | return response 61 | 62 | # Query part number 63 | try: 64 | part = search_timeout() 65 | # Extract result 66 | part = part.get('result', None) 67 | except: 68 | part = {} 69 | 70 | if not part: 71 | return part_info 72 | 73 | product_code = part.get('productCode') 74 | if product_code: 75 | part_info['part_url'] = f'https://www.lcsc.com/product-detail/{product_code}.html' 76 | 77 | category, subcategory = find_categories(part) 78 | try: 79 | part_info['category'] = category 80 | part_info['subcategory'] = subcategory 81 | except: 82 | part_info['category'] = '' 83 | part_info['subcategory'] = '' 84 | 85 | headers = SEARCH_HEADERS 86 | 87 | for key in part: 88 | if key in headers: 89 | if key == 'productImages': 90 | try: 91 | part_info[key] = part['productImages'][0] 92 | except IndexError: 93 | pass 94 | else: 95 | part_info[key] = part[key] 96 | 97 | # Parameters 98 | part_info['parameters'] = {} 99 | [parameter_key, name_key, value_key] = PARAMETERS_MAP 100 | 101 | if part.get(parameter_key, ''): 102 | for parameter in range(len(part[parameter_key])): 103 | parameter_name = part[parameter_key][parameter][name_key] 104 | parameter_value = part[parameter_key][parameter][value_key] 105 | # Append to parameters dictionary 106 | part_info['parameters'][parameter_name] = parameter_value 107 | 108 | # Pricing 109 | part_info['pricing'] = {} 110 | [pricing_key, qty_key, price_key] = PRICING_MAP 111 | 112 | for price_break in part[pricing_key]: 113 | quantity = price_break[qty_key] 114 | price = price_break[price_key] 115 | part_info['pricing'][quantity] = price 116 | 117 | part_info['currency'] = 'USD' 118 | 119 | # Extra search fields 120 | if settings.CONFIG_LCSC.get('EXTRA_FIELDS', None): 121 | for extra_field in settings.CONFIG_LCSC['EXTRA_FIELDS']: 122 | if part.get(extra_field, None): 123 | part_info['parameters'][extra_field] = part[extra_field] 124 | else: 125 | from ..common.tools import cprint 126 | cprint(f'[INFO]\tWarning: Extra field "{extra_field}" not found in search results', silent=False) 127 | 128 | return part_info 129 | 130 | 131 | def test_api() -> bool: 132 | ''' Test method for API ''' 133 | 134 | test_success = True 135 | expected = { 136 | 'productIntroEn': '25V 100pF C0G ±5% 0201 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS', 137 | 'productCode': 'C2181718', 138 | 'brandNameEn': 'TDK', 139 | 'productModel': 'C0603C0G1E101J030BA', 140 | } 141 | 142 | test_part = fetch_part_info('C2181718') 143 | if not test_part: 144 | test_success = False 145 | 146 | # Check content of response 147 | if test_success: 148 | for key, value in expected.items(): 149 | if test_part[key] != value: 150 | print(f'"{test_part[key]}" <> "{value}"') 151 | test_success = False 152 | break 153 | 154 | return test_success 155 | -------------------------------------------------------------------------------- /kintree/search/mouser_api.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..config import settings, config_interface 4 | from mouser.api import MouserPartSearchRequest 5 | 6 | SEARCH_HEADERS = [ 7 | 'Description', 8 | 'productCode', 9 | 'MouserPartNumber', 10 | 'Manufacturer', 11 | 'ManufacturerPartNumber', 12 | 'DataSheetUrl', 13 | 'ProductDetailUrl', 14 | 'ImagePath', 15 | ] 16 | PARAMETERS_MAP = [ 17 | 'ProductAttributes', 18 | 'AttributeName', 19 | 'AttributeValue', 20 | ] 21 | 22 | PRICING_MAP = [ 23 | 'PriceBreaks', 24 | 'Quantity', 25 | 'Price', 26 | 'Currency', 27 | ] 28 | 29 | 30 | def get_default_search_keys(): 31 | return [ 32 | 'ManufacturerPartNumber', 33 | 'Description', 34 | 'revision', 35 | 'keywords', 36 | 'MouserPartNumber', 37 | 'Manufacturer', 38 | 'ManufacturerPartNumber', 39 | 'ProductDetailUrl', 40 | 'DataSheetUrl', 41 | 'ImagePath', 42 | ] 43 | 44 | 45 | def setup_environment(force=False): 46 | ''' Setup environmental variables ''' 47 | 48 | api_key = os.environ.get('MOUSER_PART_API_KEY', None) 49 | if not api_key or force: 50 | mouser_api_settings = config_interface.load_file(settings.CONFIG_MOUSER_API) 51 | try: 52 | os.environ['MOUSER_PART_API_KEY'] = mouser_api_settings['MOUSER_PART_API_KEY'] 53 | except TypeError: 54 | pass 55 | 56 | 57 | def find_categories(part_details: str): 58 | ''' Find categories ''' 59 | 60 | try: 61 | return part_details['Category'], None 62 | except: 63 | return None, None 64 | 65 | 66 | def fetch_part_info(part_number: str) -> dict: 67 | ''' Fetch part data from API ''' 68 | 69 | from wrapt_timeout_decorator import timeout 70 | 71 | setup_environment() 72 | part_info = {} 73 | 74 | @timeout(dec_timeout=20) 75 | def search_timeout(): 76 | try: 77 | request = MouserPartSearchRequest('partnumber') 78 | request.part_search(part_number) 79 | except FileNotFoundError as e: 80 | error_message = repr(e.args[0]) 81 | error_message = error_message.strip("'") 82 | from ..common.tools import cprint 83 | cprint(f'[INFO] Warning: {error_message}', silent=False) 84 | finally: 85 | # Mouser 0.1.6 API update: single part list is returned, instead of dict 86 | return request.get_clean_response()[0] 87 | 88 | # Query part number 89 | try: 90 | part: dict = search_timeout() 91 | except: 92 | part = None 93 | 94 | if not part: 95 | return part_info 96 | 97 | # Check for empty response 98 | empty = True 99 | for key, value in part.items(): 100 | if value: 101 | empty = False 102 | break 103 | if empty: 104 | return part_info 105 | 106 | category, subcategory = find_categories(part) 107 | try: 108 | part_info['category'] = category 109 | part_info['subcategory'] = subcategory 110 | except: 111 | part_info['category'] = '' 112 | part_info['subcategory'] = '' 113 | 114 | headers = SEARCH_HEADERS 115 | 116 | for key in part: 117 | if key in headers: 118 | part_info[key] = part[key] 119 | 120 | # Parameters 121 | part_info['parameters'] = {} 122 | [parameter_key, name_key, value_key] = PARAMETERS_MAP 123 | 124 | for parameter in range(len(part[parameter_key])): 125 | parameter_name = part[parameter_key][parameter][name_key] 126 | parameter_value = part[parameter_key][parameter][value_key] 127 | # Append to parameters dictionary 128 | part_info['parameters'][parameter_name] = parameter_value 129 | 130 | # Pricing 131 | part_info['pricing'] = {} 132 | [pricing_key, qty_key, price_key, currency_key] = PRICING_MAP 133 | 134 | for price_break in part[pricing_key]: 135 | quantity = price_break[qty_key] 136 | price = price_break[price_key] 137 | part_info['pricing'][quantity] = price 138 | 139 | if part[pricing_key]: 140 | part_info['currency'] = part[pricing_key][0][currency_key] 141 | else: 142 | part_info['currency'] = 'USD' 143 | 144 | # Extra search fields 145 | if settings.CONFIG_MOUSER.get('EXTRA_FIELDS', None): 146 | for extra_field in settings.CONFIG_MOUSER['EXTRA_FIELDS']: 147 | if part.get(extra_field, None): 148 | part_info['parameters'][extra_field] = part[extra_field] 149 | else: 150 | from ..common.tools import cprint 151 | cprint(f'[INFO]\tWarning: Extra field "{extra_field}" not found in search results', silent=False) 152 | 153 | return part_info 154 | 155 | 156 | def test_api() -> bool: 157 | ''' Test method for API ''' 158 | 159 | test_success = True 160 | expected = { 161 | 'Description': 'MOSFETs P-channel 1.25W', 162 | 'MouserPartNumber': '621-DMP2066LSN-7', 163 | 'Manufacturer': 'Diodes Incorporated', 164 | 'ManufacturerPartNumber': 'DMP2066LSN-7', 165 | } 166 | 167 | test_part = fetch_part_info('DMP2066LSN-7') 168 | 169 | if not test_part: 170 | # Unsucessful search 171 | test_success = False 172 | else: 173 | # Check content of response 174 | for key, value in expected.items(): 175 | if test_part[key] != value: 176 | print(f'"{test_part[key]}" <> "{value}"') 177 | test_success = False 178 | break 179 | 180 | return test_success 181 | -------------------------------------------------------------------------------- /kintree/search/search_api.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | 4 | from ..config import settings, config_interface 5 | 6 | 7 | def load_from_file(search_file, test_mode=False) -> dict: 8 | ''' Fetch part data from file ''' 9 | cache_valid = settings.CACHE_VALID_DAYS * 24 * 3600 10 | 11 | # Load data from file if cache enabled 12 | if settings.CACHE_ENABLED: 13 | try: 14 | part_data = config_interface.load_file(search_file) 15 | except FileNotFoundError: 16 | return None 17 | 18 | # Check cache validity 19 | try: 20 | # Get timestamp 21 | timestamp = int(time.time() - part_data['search_timestamp']) 22 | except (KeyError, TypeError): 23 | timestamp = int(time.time()) 24 | 25 | if timestamp < cache_valid or test_mode: 26 | return part_data 27 | 28 | return None 29 | 30 | 31 | def save_to_file(part_info, search_file, update_ts=True): 32 | ''' Save part data to file ''' 33 | 34 | # Check if search/results directory needs to be created 35 | if not os.path.exists(os.path.dirname(search_file)): 36 | os.mkdir(os.path.dirname(search_file)) 37 | 38 | if update_ts: 39 | # Update timestamp 40 | part_info['search_timestamp'] = int(time.time()) 41 | 42 | # Save data if cache enabled 43 | if settings.CACHE_ENABLED: 44 | config_interface.dump_file(part_info, search_file) 45 | -------------------------------------------------------------------------------- /kintree/search/snapeda_api.py: -------------------------------------------------------------------------------- 1 | from ..config import settings 2 | from ..common.tools import download, download_with_retry 3 | 4 | API_BASE_URL = 'https://snapeda.eeinte.ch/?' 5 | SNAPEDA_URL = 'https://www.snapeda.com' 6 | 7 | 8 | def fetch_snapeda_part_info(part_number: str) -> dict: 9 | ''' Fetch SnapEDA part data from API ''' 10 | 11 | api_url = API_BASE_URL + part_number.replace(' ', '%20') 12 | data = download(api_url, timeout=10) 13 | return data if data else {} 14 | 15 | 16 | def parse_snapeda_response(response: dict) -> dict: 17 | ''' Return only relevant information from SnapEDA API response ''' 18 | 19 | data = { 20 | 'part_number': None, 21 | 'has_symbol': False, 22 | 'has_footprint': False, 23 | 'symbol_image': None, 24 | 'footprint_image': None, 25 | 'package': None, 26 | 'part_url': None, 27 | 'has_single_result': False, 28 | } 29 | 30 | number_results = int(response.get('hits', 0)) 31 | 32 | # Check for single result 33 | if number_results == 1: 34 | try: 35 | data['part_number'] = response['results'][0].get('part_number', None) 36 | data['has_symbol'] = response['results'][0].get('has_symbol', False) 37 | data['has_footprint'] = response['results'][0].get('has_footprint', False) 38 | data['package'] = response['results'][0]['package'].get('name', None) 39 | data['part_url'] = SNAPEDA_URL + response['results'][0]['_links']['self'].get('href', '') 40 | data['part_url'] += '?ref=kintree' 41 | data['has_single_result'] = True 42 | except KeyError: 43 | pass 44 | 45 | # Separate as the 'models' key does not always exist 46 | try: 47 | data['symbol_image'] = response['results'][0]['models'][0]['symbol_medium'].get('url', None) 48 | except KeyError: 49 | pass 50 | try: 51 | data['footprint_image'] = response['results'][0]['models'][0]['package_medium'].get('url', None) 52 | except KeyError: 53 | pass 54 | elif number_results > 1: 55 | try: 56 | data['part_url'] = SNAPEDA_URL + '/search/' + response['pages'][0].get('link', None).split('&')[0] + '&ref=kintree' 57 | except: 58 | pass 59 | else: 60 | pass 61 | 62 | return data 63 | 64 | 65 | def download_snapeda_images(snapeda_data: dict, silent=False) -> dict: 66 | ''' Download symbol and footprint images from SnapEDA's server ''' 67 | 68 | images = { 69 | 'symbol': None, 70 | 'footprint': None, 71 | } 72 | 73 | try: 74 | part_number = snapeda_data["part_number"].replace('/', '').lower() 75 | except: 76 | part_number = None 77 | 78 | if part_number: 79 | try: 80 | if snapeda_data['symbol_image']: 81 | # Form path 82 | image_name = f'{part_number}_symbol.png' 83 | image_location = settings.search_images + image_name 84 | 85 | # Download symbol image 86 | symbol = download_with_retry( 87 | url=snapeda_data['symbol_image'], 88 | full_path=image_location, 89 | filetype='Image', 90 | silent=silent, 91 | ) 92 | if symbol: 93 | images['symbol'] = image_location 94 | except KeyError: 95 | pass 96 | 97 | try: 98 | if snapeda_data['footprint_image']: 99 | # Form path 100 | image_name = f'{part_number}_footprint.png' 101 | image_location = settings.search_images + image_name 102 | 103 | # Download symbol image 104 | footprint = download_with_retry( 105 | url=snapeda_data['footprint_image'], 106 | full_path=image_location, 107 | filetype='Image', 108 | silent=silent, 109 | ) 110 | if footprint: 111 | images['footprint'] = image_location 112 | except KeyError: 113 | pass 114 | 115 | return images 116 | 117 | 118 | def test_snapeda_api() -> bool: 119 | ''' Test method for SnapEDA API ''' 120 | 121 | result = False 122 | 123 | # Test single result 124 | response = fetch_snapeda_part_info('TPS61221DCKR') 125 | data = parse_snapeda_response(response) 126 | images = download_snapeda_images(data, silent=True) 127 | 128 | if data['part_number'] and data['has_symbol'] and images['symbol']: 129 | result = True 130 | 131 | # Test multiple results 132 | if result: 133 | response = fetch_snapeda_part_info('1N4148W-7-F') 134 | data = parse_snapeda_response(response) 135 | if data['has_single_result']: 136 | result = False 137 | 138 | return result 139 | -------------------------------------------------------------------------------- /kintree/search/tme_api.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import collections 3 | import hashlib 4 | import hmac 5 | import os 6 | import urllib.parse 7 | import urllib.request 8 | import json 9 | 10 | # from ..common.tools import download 11 | from ..config import config_interface, settings 12 | 13 | PRICING_MAP = [ 14 | 'PriceList', 15 | 'Amount', 16 | 'PriceValue', 17 | 'Currency', 18 | ] 19 | 20 | 21 | def get_default_search_keys(): 22 | return [ 23 | 'Symbol', 24 | 'Description', 25 | '', # Revision 26 | 'Category', 27 | 'Symbol', 28 | 'Producer', 29 | 'OriginalSymbol', 30 | 'ProductInformationPage', 31 | 'Datasheet', 32 | 'Photo', 33 | ] 34 | 35 | 36 | def check_environment() -> bool: 37 | TME_API_TOKEN = os.environ.get('TME_API_TOKEN', None) 38 | TME_API_SECRET = os.environ.get('TME_API_SECRET', None) 39 | 40 | if not TME_API_TOKEN or not TME_API_SECRET: 41 | return False 42 | 43 | return True 44 | 45 | 46 | def setup_environment(force=False) -> bool: 47 | if not check_environment() or force: 48 | tme_api_settings = config_interface.load_file(settings.CONFIG_TME_API) 49 | os.environ['TME_API_TOKEN'] = tme_api_settings.get('TME_API_TOKEN', None) 50 | os.environ['TME_API_SECRET'] = tme_api_settings.get('TME_API_SECRET', None) 51 | 52 | return check_environment() 53 | 54 | 55 | # Based on TME API snippets mentioned in API documentation: https://developers.tme.eu/documentation/download 56 | # https://github.com/tme-dev/TME-API/blob/master/Python/call.py 57 | def tme_api_request(endpoint, tme_api_settings, params, api_host='https://api.tme.eu', format='json', **kwargs): 58 | TME_API_TOKEN = tme_api_settings.get('TME_API_TOKEN', None) 59 | TME_API_SECRET = tme_api_settings.get('TME_API_SECRET', None) 60 | 61 | params['Country'] = tme_api_settings.get('TME_API_COUNTRY', 'US') 62 | params['Language'] = tme_api_settings.get('TME_API_LANGUAGE', 'EN') 63 | if not TME_API_TOKEN and not TME_API_SECRET: 64 | TME_API_TOKEN = os.environ.get('TME_API_TOKEN', None) 65 | TME_API_SECRET = os.environ.get('TME_API_SECRET', None) 66 | if not TME_API_TOKEN and not TME_API_SECRET: 67 | from ..common.tools import cprint 68 | cprint('[INFO]\tWarning: Value not found for TME_API_TOKEN and/or TME_API_SECRET', silent=False) 69 | return None 70 | params['Token'] = TME_API_TOKEN 71 | params = collections.OrderedDict(sorted(params.items())) 72 | 73 | url = api_host + endpoint + '.' + format 74 | encoded_params = urllib.parse.urlencode(params, quote_via=urllib.parse.quote) 75 | signature_base = 'POST' + '&' + urllib.parse.quote(url, '') + '&' + urllib.parse.quote(encoded_params, '') 76 | hmac_value = hmac.new( 77 | TME_API_SECRET.encode(), 78 | signature_base.encode(), 79 | hashlib.sha1 80 | ).digest() 81 | api_signature = base64.encodebytes(hmac_value).rstrip() 82 | params['ApiSignature'] = api_signature 83 | 84 | data = urllib.parse.urlencode(params).encode() 85 | headers = { 86 | "Content-type": "application/x-www-form-urlencoded", 87 | } 88 | return urllib.request.Request(url, data, headers) 89 | 90 | 91 | def tme_api_query(request: urllib.request.Request) -> dict: 92 | response = None 93 | try: 94 | data = urllib.request.urlopen(request).read().decode('utf8') 95 | except urllib.error.HTTPError: 96 | data = None 97 | if data: 98 | response = json.loads(data) 99 | return response 100 | 101 | 102 | def fetch_part_info(part_number: str) -> dict: 103 | 104 | def search_product(response): 105 | found = False 106 | index = 0 107 | for product in response['Data']['ProductList']: 108 | if product['Symbol'] == part_number: 109 | found = True 110 | break 111 | index = index + 1 112 | return found, index 113 | 114 | tme_api_settings = config_interface.load_file(settings.CONFIG_TME_API) 115 | params = {'SymbolList[0]': part_number} 116 | response = tme_api_query(tme_api_request('/Products/GetProducts', tme_api_settings, params)) 117 | 118 | if response is None or response['Status'] != 'OK': 119 | return {} 120 | # in the case if multiple parts returned 121 | # (for e.g. if we looking for NE555A we could have NE555A and NE555AB in the results) 122 | found = False 123 | index = 0 124 | for product in response['Data']['ProductList']: 125 | if product['Symbol'] == part_number: 126 | found = True 127 | break 128 | index = index + 1 129 | 130 | if not found: 131 | return {} 132 | part_info = response['Data']['ProductList'][index] 133 | part_info['Photo'] = "http:" + part_info['Photo'] 134 | part_info['ProductInformationPage'] = "http:" + part_info['ProductInformationPage'] 135 | part_info['category'] = part_info['Category'] 136 | part_info['subcategory'] = None 137 | 138 | # query the parameters 139 | params = {'SymbolList[0]': part_number} 140 | response = tme_api_query(tme_api_request('/Products/GetParameters', tme_api_settings, params)) 141 | # check if accidentally no data returned 142 | if response is None or response['Status'] != 'OK': 143 | return part_info 144 | 145 | found, index = search_product(response) 146 | 147 | if not found: 148 | return part_info 149 | 150 | part_info['parameters'] = {} 151 | for param in response['Data']['ProductList'][index]["ParameterList"]: 152 | part_info['parameters'][param['ParameterName']] = param['ParameterValue'] 153 | 154 | # query the prices 155 | params = {'SymbolList[0]': part_number, 'Curreny': 'USD'} 156 | response = tme_api_query(tme_api_request('/Products/GetPrices', tme_api_settings, params)) 157 | # check if accidentally no data returned 158 | if response is None or response['Status'] != 'OK': 159 | return part_info 160 | 161 | found, index = search_product(response) 162 | 163 | if not found: 164 | part_info['currency'] = 'USD' 165 | return part_info 166 | 167 | part_info['pricing'] = {} 168 | [pricing_key, qty_key, price_key, currency_key] = PRICING_MAP 169 | 170 | for price_break in response['Data']['ProductList'][index][pricing_key]: 171 | quantity = price_break[qty_key] 172 | price = price_break[price_key] 173 | part_info['pricing'][quantity] = price 174 | 175 | part_info['currency'] = response['Data'][currency_key] 176 | 177 | # Query the files associated to the product 178 | params = {'SymbolList[0]': part_number} 179 | response = tme_api_query(tme_api_request('/Products/GetProductsFiles', tme_api_settings, params)) 180 | # check if accidentally no products returned 181 | if response is None or response['Status'] != 'OK': 182 | return part_info 183 | 184 | found, index = search_product(response) 185 | 186 | if not found: 187 | return part_info 188 | 189 | for doc in response['Data']['ProductList'][index]['Files']['DocumentList']: 190 | if doc['DocumentType'] == 'DTE': 191 | part_info['Datasheet'] = 'http:' + doc['DocumentUrl'] 192 | break 193 | return part_info 194 | 195 | 196 | def test_api(check_content=False) -> bool: 197 | ''' Test method for API ''' 198 | setup_environment() 199 | 200 | test_success = True 201 | expected = { 202 | 'Description': 'Capacitor: ceramic; MLCC; 33pF; 50V; C0G; ±5%; SMD; 0402', 203 | 'Symbol': 'CL05C330JB5NNNC', 204 | 'Producer': 'SAMSUNG', 205 | 'OriginalSymbol': 'CL05C330JB5NNNC', 206 | 'ProductInformationPage': 'http://www.tme.eu/en/details/cl05c330jb5nnnc/mlcc-smd-capacitors/samsung/', 207 | 'Datasheet': 'http://www.tme.eu/Document/7da762c1dbaf553c64ad9c40d3603826/mlcc_samsung.pdf', 208 | 'Photo': 'http://ce8dc832c.cloudimg.io/v7/_cdn_/8D/4E/00/00/0/58584_1.jpg?width=640&height=480&wat=1&wat_url=_tme-wrk_%2Ftme_new.png&wat_scale=100p&ci_sign=be42abccf5ef8119c2a0d945a27afde3acbeb699', 209 | } 210 | 211 | test_part = fetch_part_info('CL05C330JB5NNNC') 212 | 213 | # Check for response 214 | if not test_part: 215 | test_success = False 216 | 217 | if not check_content: 218 | return test_success 219 | 220 | # Check content of response 221 | if test_success: 222 | for key, value in expected.items(): 223 | if test_part[key] != value: 224 | print(f'{test_part[key]} != {value}') 225 | test_success = False 226 | break 227 | 228 | return test_success 229 | -------------------------------------------------------------------------------- /kintree/setup_inventree.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from .config import settings 4 | from .common.tools import cprint 5 | from .config import config_interface 6 | from .database import inventree_api, inventree_interface 7 | 8 | 9 | def setup_inventree(): 10 | SETUP_CATEGORIES = True 11 | SETUP_PARAMETERS = True 12 | 13 | def create_categories(parent, name, categories): 14 | category_pk, is_category_new = inventree_api.create_category(parent=parent, name=name) 15 | if is_category_new: 16 | cprint(f'[TREE]\tSuccess: Category "{name}" was added to InvenTree') 17 | else: 18 | cprint(f'[TREE]\tWarning: Category "{name}" already exists') 19 | 20 | if categories[name]: 21 | for cat in categories[name]: 22 | create_categories(parent=name, name=cat, categories=categories[name]) 23 | 24 | if SETUP_CATEGORIES or SETUP_PARAMETERS: 25 | cprint('\n[MAIN]\tStarting InvenTree setup', silent=settings.SILENT) 26 | # Load category configuration file 27 | categories = config_interface.load_file(settings.CONFIG_CATEGORIES)['CATEGORIES'] 28 | 29 | cprint('[MAIN]\tConnecting to Inventree', silent=settings.SILENT) 30 | inventree_connect = inventree_interface.connect_to_server() 31 | 32 | if not inventree_connect: 33 | sys.exit(-1) 34 | 35 | # Setup database for test 36 | inventree_api.set_inventree_db_test_mode() 37 | 38 | if SETUP_CATEGORIES: 39 | for category in categories.keys(): 40 | cprint(f'\n[MAIN]\tCreating categories in {category.upper()}') 41 | create_categories(parent=None, name=category, categories=categories) 42 | 43 | if SETUP_PARAMETERS: 44 | # Load parameter configuration file 45 | parameters = config_interface.load_file(settings.CONFIG_PARAMETERS) 46 | # cprint(parameters) 47 | cprint('\n[MAIN]\tLoading Parameters') 48 | for name, unit in parameters.items(): 49 | pk = inventree_api.create_parameter_template(name, unit) 50 | if pk > 0: 51 | cprint(f'[TREE]\tSuccess: Parameter "{name}" was added to InvenTree') 52 | else: 53 | cprint(f'[TREE]\tWarning: Parameter "{name}" already exists') 54 | 55 | 56 | if __name__ == '__main__': 57 | setup_inventree() 58 | -------------------------------------------------------------------------------- /kintree_gui.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from kintree.kintree_gui import main 3 | 4 | if __name__ == '__main__': 5 | if len(sys.argv) > 1: 6 | main(view='browser') 7 | sys.exit() 8 | main(view='flet_app') 9 | -------------------------------------------------------------------------------- /poetry.toml: -------------------------------------------------------------------------------- 1 | [virtualenvs] 2 | in-project = true 3 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "kintree" 3 | version = "1.2.99" # placeholder 4 | description = "Fast part creation in KiCad and InvenTree" 5 | authors = ["eeintech "] 6 | maintainers = ["eeintech "] 7 | license = "GPL-3.0-or-later" 8 | readme = "README.md" 9 | homepage = "https://github.com/sparkmicro/Ki-nTree" 10 | repository = "https://github.com/sparkmicro/Ki-nTree" 11 | keywords = ["inventree", "kicad", "digikey", "mouser", "component", "part", "create"] 12 | 13 | [tool.poetry.dependencies] 14 | python = ">=3.9,<3.13" 15 | # digikey-api = "^1.0.0" 16 | digikey-api = { git = "https://github.com/hurricaneJoef/digikey-api.git", branch = "master" } 17 | setuptools = "^75.6.0" 18 | flet = "^0.24.1" 19 | thefuzz = "^0.22.1" 20 | inventree = "^0.17.2" 21 | kiutils = "^1.4.8" 22 | mouser = "^0.1.6" 23 | multiprocess = "^0.70.17" 24 | pyyaml = "^6.0.2" 25 | validators = "^0.34.0" 26 | wrapt_timeout_decorator = "^1.5.1" 27 | cloudscraper = "^1.2.71" 28 | 29 | [tool.poetry.dev-dependencies] 30 | invoke = "^2.0.0" 31 | coveralls = "^3.3.1" 32 | 33 | [tool.poetry.scripts] 34 | kintree = 'kintree.kintree_gui:main' 35 | kintree_setup_inventree = 'kintree.setup_inventree:setup_inventree' 36 | 37 | [build-system] 38 | requires = ["poetry-core>=1.4.2"] 39 | build-backend = "poetry.core.masonry.api" 40 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cloudscraper==1.2.71 2 | setuptools==75.2.0 3 | https://github.com/hurricaneJoef/digikey-api/archive/refs/heads/master.zip 4 | Flet>=0.24.1,<1.0 5 | thefuzz>=0.19.0,<1.0 6 | inventree>=0.17.1,<1.0 7 | kiutils>=1.4.8,<2.0 8 | mouser>=0.1.6,<1.0 9 | multiprocess>=0.70.16,<0.71 10 | PyYAML>=6.0.1,<7.0 11 | validators>=0.19.0,<1.0 12 | wrapt_timeout_decorator>=1.5.1,<2.0 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = 3 | # - W191 - indentation contains tab 4 | # W191, 5 | # - W293 - blank lines contain whitespace 6 | W293, 7 | W605, 8 | # - E501 - line too long (82 characters) 9 | E501, E722, 10 | # - C901 - function is too complex 11 | C901, 12 | # - N802 - function name should be lowercase 13 | N802, 14 | # - N806 - variable should be lowercase 15 | N806, 16 | N812, 17 | exclude = .git,__pycache__,*/migrations/*,*/lib/*,*/bin/*,*/media/*,*/static/*,*ci_*.py* 18 | max-complexity = 20 19 | -------------------------------------------------------------------------------- /tasks.py: -------------------------------------------------------------------------------- 1 | import webbrowser 2 | 3 | from kintree.common.tools import cprint 4 | from invoke import UnexpectedExit, task 5 | 6 | 7 | @task 8 | def install(c, is_install=True): 9 | """ 10 | Install Ki-nTree dependencies 11 | """ 12 | 13 | if is_install: 14 | cprint('[MAIN]\tInstalling required dependencies') 15 | c.run('pip install -U wheel', hide='out') 16 | else: 17 | cprint('[MAIN]\tUpdating required dependencies') 18 | c.run('pip install -U -r requirements.txt', hide='out') 19 | 20 | 21 | @task 22 | def update(c): 23 | """ 24 | Update Ki-nTree dependencies 25 | """ 26 | 27 | install(c, is_install=False) 28 | 29 | 30 | @task 31 | def clean(c): 32 | """ 33 | Clean project folder 34 | """ 35 | 36 | cprint('[MAIN]\tCleaning project directory') 37 | try: 38 | c.run('find . -name __pycache__ | xargs rm -r', hide='err') 39 | except UnexpectedExit: 40 | pass 41 | try: 42 | c.run('rm .coverage', hide='err') 43 | except UnexpectedExit: 44 | pass 45 | try: 46 | c.run('rm .coverage.*', hide='err') 47 | except UnexpectedExit: 48 | pass 49 | try: 50 | c.run('rm -r dist/ build/ htmlcov', hide='err') 51 | except UnexpectedExit: 52 | pass 53 | 54 | 55 | @task(pre=[clean]) 56 | def build(c): 57 | """ 58 | Build Ki-nTree into dist/wheel 59 | """ 60 | 61 | try: 62 | c.run('pip show poetry', hide=True) 63 | except UnexpectedExit: 64 | c.run('pip install -U poetry', hide=True) 65 | 66 | cprint('[MAIN]\tBuilding Ki-nTree GUI into "dist" directory') 67 | c.run('poetry build', hide=True) 68 | 69 | 70 | @task 71 | def setup_inventree(c): 72 | """ 73 | Setup InvenTree server 74 | """ 75 | 76 | c.run('python -m kintree.setup_inventree') 77 | 78 | 79 | @task 80 | def coverage_report(c, open_browser=True): 81 | """ 82 | Show coverage report 83 | """ 84 | 85 | cprint('[MAIN]\tBuilding coverage report') 86 | c.run('coverage report') 87 | c.run('coverage html') 88 | if open_browser: 89 | webbrowser.open('htmlcov/index.html', new=2) 90 | 91 | 92 | @task 93 | def test(c, enable_api=0): 94 | """ 95 | Run Ki-nTree tests 96 | """ 97 | 98 | try: 99 | c.run('pip show coverage', hide=True) 100 | except UnexpectedExit: 101 | c.run('pip install -U coverage', hide=True) 102 | 103 | cprint('[MAIN]\tRunning tests using coverage\n-----') 104 | # Start InvenTree server 105 | c.run('cd InvenTree/ && inv server && cd ..', asynchronous=True) 106 | c.run('sleep 15') 107 | # Copy test files 108 | c.run('cp -r tests/ kintree/') 109 | # Run Tests 110 | run_tests = c.run(f'coverage run run_tests.py {enable_api}') 111 | if run_tests.exited == 0: 112 | coverage_report(c, open_browser=False) 113 | 114 | 115 | @task 116 | def python_badge(c): 117 | """ 118 | Make badge for supported versions of Python 119 | """ 120 | 121 | cprint('[MAIN]\tInstall pybadges') 122 | c.run('pip install pybadges pip-autoremove', hide=True) 123 | cprint('[MAIN]\tCreate badge') 124 | c.run('python -m pybadges --left-text="python" --right-text="3.9 | 3.10 | 3.11 | 3.12" ' 125 | '--whole-link="https://www.python.org/" --browser --embed-logo ' 126 | '--logo="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/python.svg"') 127 | cprint('[MAIN]\tUninstall pybadges') 128 | c.run('pip-autoremove pybadges -y', hide=True) 129 | c.run('pip uninstall pip-autoremove -y', hide=True) 130 | 131 | 132 | @task 133 | def style(c): 134 | """ 135 | Run PEP style checks against Ki-nTree sourcecode 136 | """ 137 | 138 | c.run('pip install -U flake8', hide=True) 139 | print("Running PEP style checks...") 140 | c.run('flake8 --extend-ignore W503 \ 141 | tasks.py run_tests.py kintree_gui.py kintree/kintree_gui.py kintree/setup_inventree.py \ 142 | kintree/common/ kintree/config/ kintree/database/ kintree/kicad/*.py kintree/search/*.py \ 143 | kintree/gui/gui.py kintree/gui/views/*.py') 144 | 145 | 146 | @task 147 | def gui(c, browser=False): 148 | """ 149 | Open GUI in either app or browser mode 150 | """ 151 | if browser: 152 | c.run('python -m kintree_gui b') 153 | return 154 | c.run('python -m kintree_gui') 155 | -------------------------------------------------------------------------------- /tests/files/FOOTPRINTS/RF.pretty/Skyworks_SKY13575_639LF.kicad_mod: -------------------------------------------------------------------------------- 1 | (module "Skyworks_SKY13575_639LF" (layer F.Cu) (tedit 5D6EEFCB) 2 | (descr "http://www.skyworksinc.com/uploads/documents/SKY13575_639LF_203270D.pdf") 3 | (tags "Skyworks") 4 | (attr smd) 5 | (fp_text reference "REF**" (at 0 -2.45) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value "Skyworks_SKY13575_639LF" (at -0.01 2.01) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start -0.96 -0.89) (end -0.71 -0.89) (layer F.SilkS) (width 0.12)) 12 | (fp_text user "%R" (at 0 -1.55) (layer F.Fab) 13 | (effects (font (size 0.5 0.5) (thickness 0.075))) 14 | ) 15 | (fp_line (start 1.22 -1.22) (end -1.22 -1.22) (layer F.CrtYd) (width 0.05)) 16 | (fp_line (start 1.22 1.22) (end 1.22 -1.22) (layer F.CrtYd) (width 0.05)) 17 | (fp_line (start -1.22 1.22) (end 1.22 1.22) (layer F.CrtYd) (width 0.05)) 18 | (fp_line (start -1.22 -1.22) (end -1.22 1.22) (layer F.CrtYd) (width 0.05)) 19 | (fp_line (start -0.8 -0.4) (end -0.8 0.8) (layer F.Fab) (width 0.1)) 20 | (fp_line (start -0.4 -0.8) (end -0.8 -0.4) (layer F.Fab) (width 0.1)) 21 | (fp_line (start 0.8 -0.8) (end -0.4 -0.8) (layer F.Fab) (width 0.1)) 22 | (fp_line (start 0.8 0.8) (end 0.8 -0.8) (layer F.Fab) (width 0.1)) 23 | (fp_line (start -0.8 0.8) (end 0.8 0.8) (layer F.Fab) (width 0.1)) 24 | (pad "2" smd rect (at -0.772 -0.2) (size 0.4 0.2) (layers "F.Cu" "F.Paste" "F.Mask")) 25 | (pad "3" smd rect (at -0.772 0.2) (size 0.4 0.2) (layers "F.Cu" "F.Paste" "F.Mask")) 26 | (pad "9" smd rect (at 0.772 0.2) (size 0.4 0.2) (layers "F.Cu" "F.Paste" "F.Mask")) 27 | (pad "10" smd rect (at 0.772 -0.2) (size 0.4 0.2) (layers "F.Cu" "F.Paste" "F.Mask")) 28 | (pad "6" smd rect (at 0 0.772 90) (size 0.4 0.2) (layers "F.Cu" "F.Paste" "F.Mask")) 29 | (pad "13" smd rect (at 0 -0.772 90) (size 0.4 0.2) (layers "F.Cu" "F.Paste" "F.Mask")) 30 | (pad "4" smd custom (at -0.866 0.602) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 31 | (zone_connect 2) 32 | (options (clearance outline) (anchor rect)) 33 | (primitives 34 | (gr_poly (pts 35 | (xy -0.106 -0.102) (xy 0.239 -0.102) (xy 0.239 -0.054) (xy 0.175 0.098) (xy -0.106 0.098) 36 | ) (width 0)) 37 | )) 38 | (pad "1" smd custom (at -0.866 -0.601) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 39 | (zone_connect 2) 40 | (options (clearance outline) (anchor rect)) 41 | (primitives 42 | (gr_poly (pts 43 | (xy -0.106 0.101) (xy 0.239 0.101) (xy 0.239 0.053) (xy 0.175 -0.099) (xy -0.106 -0.099) 44 | ) (width 0)) 45 | )) 46 | (pad "5" smd custom (at -0.4 0.871) (size 0.19 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 47 | (zone_connect 2) 48 | (options (clearance outline) (anchor rect)) 49 | (primitives 50 | (gr_poly (pts 51 | (xy 0.1 -0.299) (xy 0.1 0.101) (xy -0.1 0.101) (xy -0.1 -0.119) (xy -0.025 -0.299) 52 | ) (width 0)) 53 | )) 54 | (pad "7" smd custom (at 0.4 0.87) (size 0.19 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 55 | (zone_connect 2) 56 | (options (clearance outline) (anchor rect)) 57 | (primitives 58 | (gr_poly (pts 59 | (xy -0.1 -0.298) (xy -0.1 0.102) (xy 0.1 0.102) (xy 0.1 -0.118) (xy 0.025 -0.298) 60 | ) (width 0)) 61 | )) 62 | (pad "12" smd custom (at 0.398 -0.87) (size 0.19 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 63 | (zone_connect 2) 64 | (options (clearance outline) (anchor rect)) 65 | (primitives 66 | (gr_poly (pts 67 | (xy -0.098 -0.102) (xy -0.098 0.298) (xy 0.027 0.298) (xy 0.102 0.118) (xy 0.102 -0.102) 68 | ) (width 0)) 69 | )) 70 | (pad "14" smd custom (at -0.4 -0.869) (size 0.19 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 71 | (zone_connect 2) 72 | (options (clearance outline) (anchor rect)) 73 | (primitives 74 | (gr_poly (pts 75 | (xy 0.1 -0.103) (xy -0.1 -0.103) (xy -0.1 0.117) (xy -0.025 0.297) (xy 0.1 0.297) 76 | ) (width 0)) 77 | )) 78 | (pad "8" smd custom (at 0.871 0.6) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 79 | (zone_connect 2) 80 | (options (clearance outline) (anchor rect)) 81 | (primitives 82 | (gr_poly (pts 83 | (xy 0.101 -0.1) (xy 0.101 0.1) (xy -0.18 0.1) (xy -0.244 -0.052) (xy -0.244 -0.1) 84 | ) (width 0)) 85 | )) 86 | (pad "11" smd custom (at 0.872 -0.6) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") 87 | (zone_connect 2) 88 | (options (clearance outline) (anchor rect)) 89 | (primitives 90 | (gr_poly (pts 91 | (xy 0.1 -0.1) (xy 0.1 0.1) (xy -0.245 0.1) (xy -0.245 0.052) (xy -0.181 -0.1) 92 | ) (width 0)) 93 | )) 94 | (pad "15" smd custom (at 0 0) (size 0.29 0.29) (layers "F.Cu" "F.Mask") 95 | (options (clearance outline) (anchor rect)) 96 | (primitives 97 | (gr_poly (pts 98 | (xy -0.14 -0.36) (xy -0.36 -0.15) (xy -0.36 0.36) (xy 0.36 0.36) (xy 0.36 -0.36) 99 | ) (width 0)) 100 | )) 101 | (pad "" smd rect (at 0.185 -0.185) (size 0.29 0.29) (layers "F.Paste")) 102 | (pad "" smd rect (at 0.185 0.185) (size 0.29 0.29) (layers "F.Paste")) 103 | (pad "" smd rect (at -0.185 0.185) (size 0.29 0.29) (layers "F.Paste")) 104 | (pad "" smd custom (at -0.17 -0.17) (size 0.1 0.1) (layers "F.Paste") 105 | (options (clearance outline) (anchor rect)) 106 | (primitives 107 | (gr_poly (pts 108 | (xy 0.13 0.13) (xy 0.13 -0.16) (xy 0.04 -0.16) (xy -0.16 0.03) (xy -0.16 0.13) 109 | ) (width 0)) 110 | )) 111 | (model "${KISYS3DMOD}/RF.3dshapes/Skyworks_SKY13575_639LF.wrl" 112 | (at (xyz 0 0 0)) 113 | (scale (xyz 1 1 1)) 114 | (rotate (xyz 0 0 0)) 115 | ) 116 | ) 117 | -------------------------------------------------------------------------------- /tests/files/FOOTPRINTS/RF.pretty/Skyworks_SKY65404-31.kicad_mod: -------------------------------------------------------------------------------- 1 | (module Skyworks_SKY65404-31 (layer F.Cu) (tedit 5C4622B0) 2 | (descr http://www.skyworksinc.com/uploads/documents/SKY65404_31_201512K.pdf) 3 | (tags Skyworks) 4 | (attr smd) 5 | (fp_text reference REF** (at 0 -1.75) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value Skyworks_SKY65404-31 (at 0 1.85) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start -1.15 -1) (end 1.15 -1) (layer F.CrtYd) (width 0.05)) 12 | (fp_line (start -1.15 1) (end -1.15 -1) (layer F.CrtYd) (width 0.05)) 13 | (fp_line (start 1.15 1) (end -1.15 1) (layer F.CrtYd) (width 0.05)) 14 | (fp_line (start 1.15 -1) (end 1.15 1) (layer F.CrtYd) (width 0.05)) 15 | (fp_text user %R (at 0 0 270) (layer F.Fab) 16 | (effects (font (size 0.5 0.5) (thickness 0.075))) 17 | ) 18 | (fp_line (start -0.75 -0.375) (end -0.375 -0.75) (layer F.Fab) (width 0.1)) 19 | (fp_line (start -0.75 0.75) (end -0.75 -0.375) (layer F.Fab) (width 0.1)) 20 | (fp_line (start 0.75 0.75) (end -0.75 0.75) (layer F.Fab) (width 0.1)) 21 | (fp_line (start 0.75 -0.75) (end 0.75 0.75) (layer F.Fab) (width 0.1)) 22 | (fp_line (start -0.375 -0.75) (end 0.75 -0.75) (layer F.Fab) (width 0.1)) 23 | (fp_line (start -0.75 0.85) (end 0.75 0.85) (layer F.SilkS) (width 0.12)) 24 | (fp_line (start 0 -0.85) (end 0.75 -0.85) (layer F.SilkS) (width 0.12)) 25 | (pad 7 smd custom (at 0 0) (size 0.35 0.25) (layers F.Cu F.Paste F.Mask) 26 | (zone_connect 0) 27 | (options (clearance outline) (anchor rect)) 28 | (primitives 29 | (gr_poly (pts 30 | (xy 0.35 -0.6) (xy 0.35 0) (xy 0.35 0.6) (xy 0.1 0.6) (xy 0.1 0.65) 31 | (xy -0.1 0.65) (xy -0.1 0.6) (xy -0.35 0.6) (xy -0.35 -0.45) (xy -0.2 -0.6) 32 | (xy -0.1 -0.6) (xy -0.1 -0.65) (xy 0.1 -0.65) (xy 0.1 -0.6)) (width 0)) 33 | )) 34 | (pad 6 smd roundrect (at 0.725 -0.5) (size 0.35 0.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)) 35 | (pad 5 smd roundrect (at 0.725 0) (size 0.35 0.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)) 36 | (pad 4 smd roundrect (at 0.725 0.5) (size 0.35 0.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)) 37 | (pad 3 smd roundrect (at -0.725 0.5) (size 0.35 0.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)) 38 | (pad 2 smd roundrect (at -0.725 0) (size 0.35 0.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)) 39 | (pad 1 smd roundrect (at -0.725 -0.5) (size 0.35 0.25) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)) 40 | (model ${KISYS3DMOD}/RF.3dshapes/Skyworks_SKY65404-31.wrl 41 | (at (xyz 0 0 0)) 42 | (scale (xyz 1 1 1)) 43 | (rotate (xyz 0 0 0)) 44 | ) 45 | ) 46 | -------------------------------------------------------------------------------- /tests/files/digikey_config.yaml: -------------------------------------------------------------------------------- 1 | EXTRA_FIELDS: null 2 | SEARCH_DATASHEET: null 3 | SEARCH_DESCRIPTION: null 4 | SEARCH_KEYWORDS: null 5 | SEARCH_MANUFACTURER: null 6 | SEARCH_MPN: null 7 | SEARCH_NAME: null 8 | SEARCH_REVISION: null 9 | SEARCH_SKU: null 10 | SEARCH_SUPPLIER_URL: null 11 | SUPPLIER_INVENTREE_NAME: Digi-Key -------------------------------------------------------------------------------- /tests/files/inventree_default_db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/tests/files/inventree_default_db.sqlite3 -------------------------------------------------------------------------------- /tests/files/inventree_dev.yaml: -------------------------------------------------------------------------------- 1 | DATASHEET_UPLOAD: true 2 | ENABLE: true 3 | ENABLE_PROXY: false 4 | PASSWORD: !!binary | 5 | WVdSdGFXND0= 6 | SERVER_ADDRESS: http://127.0.0.1:8000/ 7 | USERNAME: admin 8 | PROXIES: null 9 | -------------------------------------------------------------------------------- /tests/files/kicad_map.yaml: -------------------------------------------------------------------------------- 1 | KICAD_FOOTPRINTS: 2 | Capacitors: 3 | - Capacitors 4 | Circuit Protections: 5 | - Fuses 6 | Connectors: 7 | - Connectors 8 | Crystals and Oscillators: 9 | - Crystals 10 | Diodes: 11 | - Diodes 12 | Inductors: 13 | - Inductors 14 | Integrated Circuits: 15 | - Package_SO 16 | - Package_DFN 17 | - Package_QFP 18 | - Package_QFN 19 | Mechanicals: 20 | - Mechanicals 21 | - Switches 22 | Miscellaneous: 23 | - Misc 24 | Power Management: 25 | - Package_SO 26 | - Package_GEN 27 | - Package_DFN 28 | RF: 29 | - Antennas 30 | Resistors: 31 | - Resistors 32 | Transistors: 33 | - Package_SO 34 | KICAD_LIBRARIES: 35 | Capacitors: 36 | - Capacitors 37 | Circuit Protections: 38 | - Circuit_Protections 39 | Connectors: 40 | - Connectors 41 | Crystals and Oscillators: 42 | - Crystals_Oscillators 43 | Diodes: 44 | - Diodes 45 | Inductors: 46 | - Inductors 47 | Integrated Circuits: 48 | - Integrated_Circuits 49 | Mechanicals: 50 | - Mechanicals 51 | Miscellaneous: 52 | - Miscellaneous 53 | Power Management: 54 | - Power_Management 55 | RF: 56 | - RF 57 | Resistors: 58 | - Resistors 59 | Transistors: 60 | - Transistors 61 | KICAD_TEMPLATES: 62 | Capacitors: 63 | Aluminium: capacitor-polarized 64 | Ceramic: capacitor 65 | Default: capacitor 66 | Polymer: capacitor-polarized 67 | Super Capacitors: capacitor-polarized 68 | Tantalum: capacitor-polarized 69 | Circuit Protections: 70 | Default: protection-unidir 71 | Fuse: fuse 72 | TVS: protection-unidir 73 | Connectors: 74 | Default: connector 75 | Crystals and Oscillators: 76 | Crystal 2P: crystal-2p 77 | Default: crystal-2p 78 | Oscillator 4P: oscillator-4p 79 | Diodes: 80 | Default: diode-standard 81 | LED: diode-led 82 | Schottky: diode-schottky 83 | Standard: diode-standard 84 | Zener: diode-zener 85 | Inductors: 86 | Default: inductor 87 | Ferrite Bead: ferrite-bead 88 | Power: inductor 89 | Integrated Circuits: 90 | Default: integrated-circuit 91 | EEPROM SOT23: eeprom-sot23 92 | Mechanicals: 93 | Default: default 94 | Power Management: 95 | Default: integrated-circuit 96 | RF: 97 | Default: integrated-circuit 98 | Resistors: 99 | Default: resistor 100 | Surface Mount: resistor-sm 101 | Through Hole: resistor 102 | Transistors: 103 | Default: transistor-nfet 104 | N-Channel FET: transistor-nfet 105 | NPN: transistor-npn 106 | P-Channel FET: transistor-pfet 107 | PNP: transistor-pnp 108 | -------------------------------------------------------------------------------- /tests/files/results.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkmicro/Ki-nTree/070f29a507d91433ff2cb0525ee8673ef2ac6cbb/tests/files/results.tgz -------------------------------------------------------------------------------- /tests/test_samples.yaml: -------------------------------------------------------------------------------- 1 | Capacitors: 2 | ## 0402 0.1u 16V X7R 3 | 0402B104K160CT: original 4 | # Equivalent 5 | CL05B104KO5NNNC: alternate_mpn 6 | # 'Fake' Equivalent (Temperature Grade) 7 | C0402C104K4PACTU: fake_alternate 8 | # Aluminum 9 | EEE-HA1A101WP: original 10 | # Tantalum 11 | T491A106K010AT: original 12 | # Aluminum-Polymer 13 | RSA0J331MCN1GS: original 14 | # Tantalum-Polymer 15 | 10TPE68M: original 16 | # Super-Capacitor 17 | CPH3225A: original 18 | 19 | Circuit Protections: 20 | # TVS 21 | SMAJ5.0CA-13-F: original 22 | # ESD 23 | ESDALC14-1BF4: original 24 | # Fuse 25 | 0603SFP150F/32-2: original 26 | # PTC 27 | 0ZCM0005FF2G: original 28 | 29 | Connectors: 30 | # Board-to-board 31 | 10144517-061802LF: original 32 | # Interface, microSD 33 | DM3CS-SF: original 34 | # Interface, USB Type-C 35 | USB4085-GF-A: original 36 | # Interface, Audio Jack 37 | SJ-3524-SMT-TR: original 38 | # Interface, Ethernet 39 | J3011G21DNLT: original 40 | # Coaxial 41 | H.FL-R-SMT(C)(10): original 42 | # FPC 43 | 0522713069: original 44 | # Header Male (Power) 45 | 0533980271: original 46 | # Header Female 47 | 20021321-00010C4LF: original 48 | 49 | Crystals and Oscillators: 50 | # 2-pin 32.768kHz Crystal 51 | ABS07-120-32.768KHZ-T: original 52 | # 4-pin 40MHz Oscillator 53 | KC2520C40.0000C2YE00: original 54 | 55 | Diodes: 56 | # General Purpose 57 | 1N4148W-7-F: original 58 | # Zener 59 | MMSZ5231B-7-F: original 60 | # LED 61 | LTST-C191KGKT: original 62 | # Schottky 63 | PMEG10010ELRX: original 64 | 65 | Inductors: 66 | # Power 67 | NRS5030T4R7MMGJV: original 68 | # Ferrite Bead 69 | BLM18AG601SN1D: original 70 | 71 | Integrated Circuits: 72 | # Logic 73 | SN74LVC2T45DCTR: original 74 | # Memory 75 | MX25R6435FM2IL0: original 76 | # Microcontroller 77 | STM32F730R8T6: original 78 | # Interface 79 | MAX9867ETJ+T: original 80 | # Sensor 81 | BME280: original 82 | 83 | Mechanicals: 84 | # Switch 85 | TL1105SF160Q: original 86 | 87 | Power Management: 88 | # Buck, Adjustable 89 | AOZ1282CI: original 90 | # Buck, Fixed 91 | SC189CULTRT: original 92 | # Boost, Fixed 93 | TPS61221DCKR: original 94 | # LDO, Adjustable 95 | LP3982IMM-ADJ/NOPB: original 96 | # LDO, Fixed 97 | AP2210K-3.3TRG1: original 98 | 99 | Resistors: 100 | # 10K/5% 101 | ### Surface Mount 102 | ## 0603 103 | RK73B1JTTD103J: original 104 | # Equivalent 105 | ERJ-3GEYJ103V: alternate_mpn 106 | # 'Fake' Equivalent (Tolerance) 107 | RC0603FR-0710KL: fake_alternate 108 | ## 0402 109 | RC0402FR-07100RL: original 110 | # Equivalent 111 | CRCW0402100RFKEDC: alternate_mpn 112 | # 'Fake' Equivalent (Power) 113 | ERJ-2GEJ101X: fake_alternate 114 | ### Through Hole 115 | CF14JT10K0: original 116 | # Equivalent 117 | CFR16J10K: alternate_mpn 118 | # 'Fake' Equivalent (Temperature) 119 | CBT25J10K: fake_alternate 120 | ### Array 121 | # ('original', 'EXB-28V103JX'), 122 | # # Equivalent 123 | # ('alternate_mpn', 'CAT10-103J4LF'), 124 | # # 'Fake' Equivalent (Power) 125 | # ('fake_alternate', 'EXB-N8V103JX'), 126 | # ### Potentiometer 127 | # ('original', '3590S-2-103L'), 128 | # ### NTC 129 | # ('original', 'NCP15XH103J03RC'), 130 | 131 | RF: 132 | # Filter (Balun) 133 | 2450BM14E0003001T: original 134 | 135 | Transistors: 136 | # NPN 137 | MMBT3904-7-F: original 138 | # PNP 139 | MMBT3906TT1G: original 140 | # N-Channel FET 141 | 2N7002-7-F: original 142 | # P-Channel FET 143 | BSS84-7-F: original 144 | --------------------------------------------------------------------------------