3 Commits

Author SHA1 Message Date
Gautam Peri 43f519191e Update generate-bom to 0.8 2025-05-13 00:47:56 +00:00
Daniel Lindmark 48b12293a9 Add Actions 2024-07-28 18:38:35 -05:00
AllSpiceUser 1d8cf61689 Merge pull request 'Add V3 files' (#1) from develop into main
Reviewed-on: https://hub.allspice.io/AllSpice-Demos/Altium-Demo/pulls/1
2024-07-28 22:45:09 +00:00
11 changed files with 294 additions and 2 deletions
+21
View File
@@ -0,0 +1,21 @@
columns:
- name: "Manufacturer"
part_attributes:
- "Manufacturer"
- "MANUFACTURER"
sort: "asc"
- name: "Part Number"
part_attributes:
- "PART"
- "MANUFACTURER #"
- "_part_id"
remove_rows_matching: "TP|MTG|FID"
- name: "Designator"
part_attributes: "Designator"
grouped_values_separator: ", "
grouped_values_sort: "asc"
- name: "Description"
part_attributes:
- "PART DESCRIPTION"
- "_description"
+110
View File
@@ -0,0 +1,110 @@
#! /usr/bin/env python3
# Generate a Netlist from a PcbDoc file.
# For more information, read the README file in this directory.
import argparse
import os
import sys
from contextlib import ExitStack
from allspice import AllSpice
from allspice.utils.netlist_generation import generate_netlist
if __name__ == "__main__":
print("Hello World")
# Parse command line arguments. If you're writing a special purpose script,
# you can hardcode these values instead of using command line arguments.
parser = argparse.ArgumentParser(
prog="generate_pcb_netlist", description="Generate a netlist from a PCB file."
)
parser.add_argument("repository", help="The repo containing the project")
parser.add_argument(
"pcb_file",
help="The path to the PCB file in the source repo.",
)
parser.add_argument(
"--source_ref",
help="The git reference the netlist should be generated for (eg. branch name, tag name, commit SHA). Defaults to main.",
default="main",
)
parser.add_argument(
"--allspice_hub_url",
help="The URL of your AllSpice Hub instance. Defaults to https://hub.allspice.io.",
)
parser.add_argument(
"--output_file",
help="The path to the output file. If absent, the output will direct to the command line.",
)
args = parser.parse_args()
# Use Environment Variables to store your auth token. This keeps your token
# secure when sharing code.
auth_token = os.environ.get("ALLSPICE_AUTH_TOKEN")
if auth_token is None:
print("Please set the environment variable ALLSPICE_AUTH_TOKEN")
exit(1)
if args.allspice_hub_url is None:
allspice = AllSpice(token_text=auth_token)
else:
allspice = AllSpice(
token_text=auth_token, allspice_hub_url=args.allspice_hub_url
)
try:
# Test connection and key
print("AllSpice Version: " + allspice.get_version())
# Test private API call
print("API-Token belongs to user: " + allspice.get_user().username)
except Exception as e:
print(f"Could not connect to AllSpice Hub: {e}")
exit(1)
repo_owner, repo_name = args.repository.split("/")
try:
print(f"repo_owner={repo_owner}, repo_name={repo_name}")
repository = allspice.get_repository(repo_owner, repo_name)
except Exception as e:
print(f"Could not find repository {args.repository}: {e}")
exit(1)
pcb_file = args.pcb_file
print("Generating PCB Netlist...🏃", file=sys.stderr)
netlist_rows = generate_netlist(
allspice,
repository,
pcb_file,
args.source_ref,
)
with ExitStack() as stack:
if args.output_file is not None:
writer = stack.enter_context(open(args.output_file, "w"))
else:
writer = sys.stdout
nets = list(netlist_rows.keys())
# It's helpful to sort here to generate repeatable netlist files
nets.sort()
# You can change formatting here
for net in nets:
writer.write(net + "\n")
pins_on_net = netlist_rows[net]
try:
# Convert to list if it's not already, and then sort
if not isinstance(pins_on_net, list):
pins_on_net = list(pins_on_net)
pins_on_net.sort()
except Exception as e:
print(f"Error sorting pins on net {net}: {e}", file=sys.stderr)
writer.write(" " + " ".join(pins_on_net) + "\n")
print("Generated PCB netlist.", file=sys.stderr)
+1
View File
@@ -0,0 +1 @@
print("Hello World!")
+57
View File
@@ -0,0 +1,57 @@
# HelloWorld.py
# If you're new to scripting, this is a great place to start.
# Hello World starts you out easy with some simple server requests.
# This will help you troubleshoot your connection and show you the basics of making an api request
#
# For more information read our README.md
from allspice import AllSpice
import argparse, sys
print("Starting Test")
parser = argparse.ArgumentParser(
prog="Allspice_API_BIST", description="Test connection and execution of API actions"
)
parser.add_argument(
"--allspice_hub_url",
help="The URL of your AllSpice Hub instance. Defaults to https://hub.allspice.io.",
)
parser.add_argument(
"--allspice_token",
help="Your AllSpice application token. Generate a token: https://hub.allspice.io/user/settings/applications",
)
print("Parsing args")
args = parser.parse_args()
auth_token = args.allspice_token
if auth_token is None:
print("Please supply a token with --allspice_token <your_token> Generate a token: https://hub.allspice.io/user/settings/applications")
sys.exit(1)
print(f"Auth token {auth_token}")
if args.allspice_hub_url is None:
allspice = AllSpice(token_text="https://hub.allspice.io")
else:
try:
allspice = AllSpice(
token_text=auth_token, allspice_hub_url=args.allspice_hub_url
)
except Exception as e:
print("Error")
sys.exit(1)
print("Finish making connection")
# Test connection and key
print("AllSpice Version: " + allspice.get_version())
# Test private API call
print("API-Token belongs to user: " + allspice.get_user().username)
print("End test")
+2
View File
@@ -0,0 +1,2 @@
py-allspice~=3.0
rich~=13.0
+47
View File
@@ -0,0 +1,47 @@
# AllSpice Running common Actions workflow
# Action triggers on push and issues
# Action runs "generate-bom-altium" action
# .allspice/workflows/generate_bom.yml
name: Generate BOM
on:
push:
issues:
types: [opened, closed, reopened]
jobs:
Generate_BOM:
runs-on: ubuntu-latest
steps:
# Checkout is only needed if columns.json is committed in your Altium project repo.
- name: Checkout
uses: actions/checkout@v3
- name: Generate BOM
uses: https://hub.allspice.io/Actions/generate-bom@v0.8
with:
# The path to the project file in your repo (.PrjPcb for Altium, .DSN for OrCad).
source_path: Archimajor.PrjPcb
# [optional] A path to a YAML file mapping columns to the component attributes
# This file must be provided.
# Default: 'columns.json'
columns: .allspice/columns.yml
# [optional] The path to the output file that will be generated.
# Default: 'bom.csv'
output_file_name: bom.csv
# [optional] A comma-separated list of columns to group the BOM by. If empty
# or not present, the BOM will be flat.
# Default: ''
group_by: 'Part Number'
# [optional] The variant of the project to generate the BOM for. If empty
# or not present, the BOM will be generated for the default variant.
# Default: ''
variant: ''
# Print bom.csv to terminal
- name: Show BOM
run: cat bom.csv
- name: Upload file as artifact
uses: actions/upload-artifact@v3
with:
name: BOM.csv
path: bom.csv
+54
View File
@@ -0,0 +1,54 @@
# Python-py-allspice demo repository
# This workflow demonstrates how to use Python and py-allspice to interact with the AllSpice API
# AllSpice Actions documentation: https://learn.allspice.io/docs/actions-cicd
name: Python-py-allspice
on:
push:
issues:
types: [opened, closed, reopened]
jobs:
py-allspice test:
runs-on: ubuntu-latest
steps:
# Check out repository code
- name: "[📚->🖥️] Check out repository code"
uses: actions/checkout@v3
- name: "[🔎->📂] List files in repo 🔎"
run: |
ls -la ${{ allspice.workspace }}
# Installs python requirements from the requirements.txt file
- name: "[🤼->🖥️] Install python requirements"
run: pip install -r .allspice/utils/requirements.txt
# Call a python script from the .allspice/utils directory
- name: "[🏃->🐍] Run .allspice/utils/hello-world.py 🔎"
run: python .allspice/utils/hello-world.py
# Run the py-allspice self-test script, this will ping the server and verify the API is working
# Parameters: ${allspice.server_url} and ${allspice.token} are automatic Workflow variables and are used to authenticate the AllSpice API
- name: "[🔑->🕸️] Test AllSpice API with py-allspice 🔎"
run: python .allspice/utils/py-allspice-BIST.py --allspice_hub_url ${{ allspice.server_url }} --allspice_token ${{ allspice.token }}
# Generate a netlist from Altium .PcbDoc file
# Run the generate_netlist.py script from the .allspice/utils directory
- name: Generate Netlist
run: |
echo -e "repo ${{ allspice.repository }}"
ALLSPICE_AUTH_TOKEN=${{ allspice.token }} python .allspice/utils/generate_netlist.py "${{ allspice.repository }}" "Archimajor.PcbDoc" --allspice_hub_url "${{ allspice.server_url }}" --output_file Archimajor.pcbdoc.netlist.txt
# Print the netlist file to the terminal
- name: Show Netlist 🔎
run: cat Archimajor.pcbdoc.netlist.txt
# Archive the netlist file as an artifact file
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
name: Archimajor.PcbDoc.netlist.txt
path: Archimajor.pcbdoc.netlist.txt
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -1,8 +1,8 @@
Description,Designator,Footprint,Quantity,MANUFACTURER,MANUFACTURER #
"CAP CER 0603 100nF 50V 10% X7R","C1, C15, C18, C23A, C23B, C23C, C23D, C23E, C36, C47A, C47B, C47C, C47D, C47E, C47F, C47G, C47H, C95, C121A, C121B, C121C, C121D, C121E, C121F, C121G, C121H, C122A, C122B, C122C, C122D, C122E, C122F, C122G, C122H, C199, C202, C203","C0603","37","Kemet","C0603C104K5RACTU"
"CAP CER 0.1UF 6.3V 10% X5R 0201","C2, C60A, C60B, C60C, C60D, C60E, C62A, C62B, C62C, C62D, C62E, C67, C78, C91, C100, C105, C106, C149A, C149B, C149C, C149D, C149E, C149F, C149G, C149H, C204, C205, C206, C207, C208, C215, C217","C0201 Large Pads","32","Samsung","CL03A104KQ3NNNC"
"CAP CER 0402 TBD","C3","C0402","1","TBD","TBD"
"CAP CER 0.1UF 6.3V 10% X5R 0201","C2, C60A, C60B, C60C, C60D, C62A, C62B, C62C, C62D, C67, C78, C91, C100, C105, C106, C149A, C149B, C149C, C149D, C149E, C149F, C149G, C149H, C204, C205, C206, C207, C208, C215, C217","C0201 Large Pads","30","Samsung","CL03A104KQ3NNNC"
"CAP CER 0402 TBD, CAP CER 0402 22pF 50V 5% C0G","C3, C151","C0402","2","TBD, AVX","TBD, 04025A220JAT2A"
"CAP CER 47UF 10V X5R 1210","C4, C5","C1210","2","Murata","GRM32ER61A476KE20L"
"CAP CER 4.7UF 50V X7R 1210","C6, C7, C440","C1210","3","Murata","GRM32ER71H475KA88L"
"Capacitor Non Polarized","C8, C9, C10, C11, C27, C50, C153, C154, C209, C211","C0603","10","","DNI-C0603TBD"
1 Description Designator Footprint Quantity MANUFACTURER MANUFACTURER #
2 CAP CER 0603 100nF 50V 10% X7R C1, C15, C18, C23A, C23B, C23C, C23D, C23E, C36, C47A, C47B, C47C, C47D, C47E, C47F, C47G, C47H, C95, C121A, C121B, C121C, C121D, C121E, C121F, C121G, C121H, C122A, C122B, C122C, C122D, C122E, C122F, C122G, C122H, C199, C202, C203 C0603 37 Kemet C0603C104K5RACTU
3 CAP CER 0.1UF 6.3V 10% X5R 0201 C2, C60A, C60B, C60C, C60D, C60E, C62A, C62B, C62C, C62D, C62E, C67, C78, C91, C100, C105, C106, C149A, C149B, C149C, C149D, C149E, C149F, C149G, C149H, C204, C205, C206, C207, C208, C215, C217 C2, C60A, C60B, C60C, C60D, C62A, C62B, C62C, C62D, C67, C78, C91, C100, C105, C106, C149A, C149B, C149C, C149D, C149E, C149F, C149G, C149H, C204, C205, C206, C207, C208, C215, C217 C0201 Large Pads 32 30 Samsung CL03A104KQ3NNNC
4 CAP CER 0402 TBD CAP CER 0402 TBD, CAP CER 0402 22pF 50V 5% C0G C3 C3, C151 C0402 1 2 TBD TBD, AVX TBD TBD, 04025A220JAT2A
5 CAP CER 47UF 10V X5R 1210 C4, C5 C1210 2 Murata GRM32ER61A476KE20L
6 CAP CER 4.7UF 50V X7R 1210 C6, C7, C440 C1210 3 Murata GRM32ER71H475KA88L
7 Capacitor Non Polarized C8, C9, C10, C11, C27, C50, C153, C154, C209, C211 C0603 10 DNI-C0603TBD
8 CAP CER 10nF 50V X7R 0402 C12A, C12B, C12C, C12D, C12E, C30A, C30B, C30C, C30D, C30E, C40, C43, C71, C77, C84, C86, C157, C158, C159, C160, C171, C214, C216 C0402 23 Murata GRM155R71H103JA88D
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.