Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hierarchical template handling #212

Merged
merged 5 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ CATEGORY_NAME:
- SUPPLIER_2_PARAMETER_NAME_1
```

It is also possible to cross reference the mappings of different categories. To define one or multiple parent categories a parameter named `parent` can be added where the items then are the desired parent categories. If a parameter name is present in both parent and child, the childs definition will override the parent.

A template image for an category can be set by using the `image` parameter. The sole item in this parameter must the filename of an already existing part image on the the InvenTree server.
eeintech marked this conversation as resolved.
Show resolved Hide resolved

Refer to [this file](https://github.com/sparkmicro/Ki-nTree/blob/main/kintree/config/inventree/supplier_parameters.yaml) as a starting point / example.

#### Part Number Search
Expand Down
42 changes: 27 additions & 15 deletions kintree/config/config_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,27 +433,39 @@ def add_supplier_category(categories: dict, supplier_config_path: str) -> bool:

def load_category_parameters(categories: list, supplier_config_path: str) -> dict:
''' Load Supplier parameters mapping from Supplier settings file '''
def find_parameters(output_dict, category_list):
category_parameters = None
combined = ''
for category in reversed(category_list):
if category:
combined = category + combined
if combined in category_file:
category_parameters = category_file[combined]
break
if category in category_file:
category_parameters = category_file[category]
break
combined = '/' + combined
if not category_parameters:
return
if 'parent' in category_parameters:
for parent in category_parameters['parent']:
find_parameters(output_dict, [parent])
del category_parameters['parent']

for parameter in category_parameters.keys():
if category_parameters[parameter]:
for supplier_parameter in category_parameters[parameter]:
output_dict[supplier_parameter] = parameter

try:
category_file = load_file(supplier_config_path)
except:
return None
category_parameters = None
for category in reversed(categories):
try:
category_parameters = category_file[category]
break
except:
pass
if not category_parameters:
return None

category_parameters_inversed = {}
for parameter in category_parameters.keys():
if category_parameters[parameter]:
for supplier_parameter in category_parameters[parameter]:
category_parameters_inversed[supplier_parameter] = parameter

# print(category_parameters_inversed)
find_parameters(category_parameters_inversed, categories)

return category_parameters_inversed


Expand Down
65 changes: 30 additions & 35 deletions kintree/config/inventree/supplier_parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,43 @@
# Each template parameter can match to multiple suppliers parameters
# Categories (main keys) should match categories in the categories.yaml file
# Parameter template names should match those found in the parameters.yaml file
Base:
Temperature Range:
- Operating Temperature
Package Type:
- Package / Case
Passives:
Tolerance:
- Tolerance
Capacitors:
parent:
- Base
- Passives
ESR:
- ESR (Equivalent Series Resistance)
Package Height:
- Height - Seated (Max)
- Thickness (Max)
Package Size:
- Size / Dimension
Package Type:
- Package / Case
Rated Voltage:
- Voltage - Rated
- Voltage Rated
Temperature Grade:
- Temperature Coefficient
Temperature Range:
- Operating Temperature
Tolerance:
- Tolerance
Value:
- Capacitance
Circuit Protections:
parent:
- Base
Breakdown Voltage:
- Voltage - Breakdown (Min)
Capacitance:
- Capacitance @ Frequency
Clamping Voltage:
- Voltage - Clamping (Max) @ Ipp
Package Type:
- Package / Case
Rated Current:
- Current Rating (Amps)
- Current - Max
Expand All @@ -42,8 +49,6 @@ Circuit Protections:
- Voltage - Max
Standoff Voltage:
- Voltage - Reverse Standoff (Typ)
Temperature Range:
- Operating Temperature
Value:
- Manufacturer Part Number
Connectors:
Expand Down Expand Up @@ -81,6 +86,8 @@ Connectors:
Value:
- Manufacturer Part Number
Crystals and Oscillators:
parent:
- Base
Frequency Stability:
- Frequency Stability
Frequency Tolerance:
Expand All @@ -91,26 +98,22 @@ Crystals and Oscillators:
- Height - Seated (Max)
Package Size:
- Size / Dimension
Package Type:
- Package / Case
Rated Current:
- Current - Supply (Max)
Rated Voltage:
- Voltage - Supply
Temperature Range:
- Operating Temperature
Value:
- Frequency
Diodes:
parent:
- Base
Forward Voltage:
- Voltage - Forward (Vf) (Max) @ If
- Voltage - Forward (Vf) (Typ)
Function Type:
- Diode Type
LED Color:
- Color
Package Type:
- Package / Case
Rated Current:
- Current - Average Rectified (Io)
Rated Power:
Expand All @@ -119,11 +122,13 @@ Diodes:
- Voltage - DC Reverse (Vr) (Max)
- Voltage - Zener (Nom) (Vz)
Temperature Range:
- Operating Temperature
- Operating Temperature - Junction
Value:
- Manufacturer Part Number
Inductors:
parent:
- Base
- Passives
ESR:
- DC Resistance (DCR)
- DC Resistance (DCR) (Max)
Expand All @@ -132,23 +137,19 @@ Inductors:
- Height (Max)
Package Size:
- Size / Dimension
Package Type:
- Package / Case
Rated Current:
- Current Rating (Max)
- Current Rating (Amps)
Saturation Current:
- Current - Saturation
Shielding:
- Shielding
Temperature Range:
- Operating Temperature
Tolerance:
- Tolerance
Value:
- Inductance
- Impedance @ Frequency
Integrated Circuits:
parent:
- Base
Frequency:
- Clock Frequency
- Speed
Expand All @@ -166,20 +167,18 @@ Integrated Circuits:
- Memory Size
Number of Channels:
- Channels per Circuit
Package Type:
- Package / Case
Rated Voltage:
- Voltage - VCCA
- Voltage - VCCB
- Voltage - Supply
- Voltage - Supply (Vcc/Vdd)
- Voltage - Supply, Digital
- Voltage - Supply, Single (V+)
Temperature Range:
- Operating Temperature
Value:
- Manufacturer Part Number
Mechanicals:
parent:
- Base
Function Type:
- Circuit
- Type
Expand All @@ -195,11 +194,11 @@ Mechanicals:
- Screw, Thread Size
Rated Current:
- Contact Rating @ Voltage
Temperature Range:
- Operating Temperature
Value:
- Manufacturer Part Number
Power Management:
parent:
- Base
(Min) Output Voltage:
- Voltage - Output (Min/Fixed)
Frequency:
Expand All @@ -220,30 +219,26 @@ Power Management:
- Current - Quiescent (Iq)
Rated Current:
- Current - Output
Temperature Range:
- Operating Temperature
Value:
- Manufacturer Part Number
RF:
parent:
- Base
Frequency:
- Frequency Range
Function Type: null
Package Type:
- Package / Case
Rated Voltage: null
Temperature Range:
- Operating Temperature
Value:
- Manufacturer Part Number
Resistors:
parent:
- Passives
Package Type:
- Supplier Device Package
Rated Power:
- Power (Watts)
Temperature Range:
- Operating Temperature
Tolerance:
- Tolerance
Value:
- Resistance
Transistors:
Expand Down
19 changes: 14 additions & 5 deletions kintree/database/inventree_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,8 @@ def get_part_info(part_id: int) -> str:

def set_part_number(part_id: int, ipn: str) -> bool:
''' Set InvenTree part number for specified Part ID '''
global inventree_api

part = Part(inventree_api, part_id)
part._data['IPN'] = ipn
part.save()
data = {'IPN': ipn}
update_part(part_id, data)

if Part(inventree_api, part_id).IPN == ipn:
return True
Expand Down Expand Up @@ -436,6 +433,18 @@ def create_part(category_id: int, name: str, description: str, revision: str, ip
return 0


def update_part(pk: int, data: dict) -> int:
'''Update an existing parts data'''
global inventree_api

part = Part(inventree_api, pk)
if part:
part.save(data=data)
return part.pk
else:
return 0


def create_company(company_name: str, manufacturer=False, supplier=False) -> bool:
''' Create InvenTree company '''
global inventree_api
Expand Down
24 changes: 18 additions & 6 deletions kintree/database/inventree_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,11 @@ def translate_form_to_inventree(part_info: dict, category_tree: list, is_custom=
for supplier_param, inventree_param in parameter_map.items():
# Some parameters may not be mapped
if inventree_param not in inventree_part['parameters'].keys():
if supplier_param != 'Manufacturer Part Number':
if supplier_param == 'Manufacturer Part Number':
inventree_part['parameters'][inventree_param] = part_info['manufacturer_part_number']
elif inventree_param == 'image':
inventree_part['existing_image'] = supplier_param
eeintech marked this conversation as resolved.
Show resolved Hide resolved
else:
try:
parameter_value = part_tools.clean_parameter_value(
category=category_tree[0],
Expand All @@ -296,16 +300,15 @@ def translate_form_to_inventree(part_info: dict, category_tree: list, is_custom=
inventree_part['parameters'][inventree_param] = parameter_value
except KeyError:
parameters_missing.append(supplier_param)
else:
inventree_part['parameters'][inventree_param] = part_info['manufacturer_part_number']

if parameters_missing:
msg = '[INFO]\tWarning: The following parameters were not found in supplier data:\n'
msg += str(parameters_missing)
cprint(msg, silent=settings.SILENT)

# Check for missing InvenTree parameters and fill value with dash
for inventree_param in parameter_map.values():
if inventree_param == 'image':
continue
if inventree_param not in inventree_part['parameters'].keys():
inventree_part['parameters'][inventree_param] = '-'

Expand Down Expand Up @@ -588,7 +591,11 @@ def inventree_create(part_info: dict, kicad=False, symbol=None, footprint=None,
if part_pk > 0:
if new_part:
cprint('[INFO]\tSuccess: Added new part to InvenTree', silent=settings.SILENT)
if inventree_part['image']:
if inventree_part.get('existing_image', ''):
inventree_api.update_part(
part_pk,
data={'existing_image': inventree_part['existing_image']})
elif inventree_part['image']:
# Add image
image_result = inventree_api.upload_part_image(inventree_part['image'], part_pk)
if not image_result:
Expand Down Expand Up @@ -752,6 +759,7 @@ def inventree_create_alternate(part_info: dict, part_id='', part_ipn='', show_pr
# Translate to InvenTree part format
category_tree = inventree_api.get_category_tree(part.category)
category_tree = list(category_tree.values())
category_tree.reverse()
inventree_part = translate_form_to_inventree(
part_info=part_info,
category_tree=category_tree,
Expand All @@ -760,7 +768,11 @@ def inventree_create_alternate(part_info: dict, part_id='', part_ipn='', show_pr
# If the part has no image yet try to upload it from the data
if not part.image:
image = part_info.get('image', '')
if image:
existing_image = inventree_part.get('existing_image', '')
if existing_image:
inventree_api.update_part(pk=part_pk,
data={'existing_image': existing_image})
elif image:
inventree_api.upload_part_image(image_url=image, part_id=part_pk)

# create or update parameters
Expand Down
Loading