Add all-type Description Format reference (RES/CAP/diode/transistor/... per Altium SOP); add update-existing-part flow + find-part command
parent
aa76bdc573
commit
1e3c22f34f
135
SKILL.md
135
SKILL.md
|
|
@ -9,10 +9,13 @@ description: >-
|
|||
(per-typeid version, changelog, backfill), fills a per-part workbook, loops on human
|
||||
verification, then takes the Altium symbol (.SchLib) and footprint (.PcbLib), fills the
|
||||
Library/Footprint columns, assembles a part folder (xlsx, datasheet, symbol, footprint) and
|
||||
pushes it to the library repo under its Class. Use WHENEVER the user uploads a component
|
||||
datasheet, builds a library entry, adds a parameter to a type template, or pushes a part to
|
||||
Gitea. ALWAYS trigger on "\datasheet", "\library", or "\library-manager", or any
|
||||
component-library / datasheet-extraction task.
|
||||
pushes it to the library repo under its Class. Can also UPDATE a part already in the library
|
||||
(revise its values, symbol, footprint, or datasheet) instead of hard-stopping on a duplicate.
|
||||
Every Description it writes follows Vecmocon's strict Altium Description Format. Use WHENEVER
|
||||
the user uploads a component datasheet, builds a library entry, adds a parameter to a type
|
||||
template, updates/revises/corrects an existing part, or pushes a part to Gitea. ALWAYS trigger
|
||||
on "\datasheet", "\library", or "\library-manager", or any component-library /
|
||||
datasheet-extraction / library-update task.
|
||||
---
|
||||
|
||||
# Library Manager
|
||||
|
|
@ -33,11 +36,15 @@ existing parts** (backfill). When something is ambiguous, ask a specific questio
|
|||
guessing. It is always better to ask one more question than to write the wrong thing into the
|
||||
library.
|
||||
|
||||
One more thing to confirm when a part **already exists**: whether to **update it or stop**
|
||||
(don't silently overwrite), and if updating, **which fields change** (values, symbol/footprint,
|
||||
datasheet). An update still goes through the same verification loop before anything is pushed.
|
||||
|
||||
**Pushing is the exception — push automatically.** Once a part is verified and assembled (or a
|
||||
template/version change has been made), push to Gitea **on your own, without asking for
|
||||
confirmation**. Never add a "shall I push?" step — just push, then tell the user where it
|
||||
landed. (You still flag a genuine symbol/footprint mismatch, because that's a correctness
|
||||
issue, not a push confirmation.)
|
||||
template/version change has been made, or a verified update is ready), push to Gitea **on your
|
||||
own, without asking for confirmation**. Never add a "shall I push?" step — just push, then tell
|
||||
the user where it landed. (You still flag a genuine symbol/footprint mismatch, because that's a
|
||||
correctness issue, not a push confirmation.)
|
||||
|
||||
## Inputs
|
||||
|
||||
|
|
@ -154,8 +161,13 @@ stop; re-doing an existing part would only risk overwriting good data.
|
|||
python scripts/gitea_components.py check-mpn --mpn <MPN> --make <make>
|
||||
```
|
||||
|
||||
`EXISTS …` (exit 3) → **stop and tell the user the part is already present in Gitea. End
|
||||
here.** `ABSENT` (exit 0) → continue.
|
||||
`ABSENT` (exit 0) → this is a **new part**; continue to step 2.
|
||||
|
||||
`EXISTS …` (exit 3) → the part is already in Gitea. Don't silently overwrite it, but don't
|
||||
dead-end either — **ask the user whether they want to update the existing part or stop.** If
|
||||
they want to revise it (new/corrected values, a swapped symbol/footprint, a newer datasheet),
|
||||
go to *Updating an existing part*. If not, stop here. (If the user's request already said
|
||||
"update"/"revise"/"fix" this part, take that as the answer and go straight to the update flow.)
|
||||
|
||||
### 2. Classify → typeid (and its Class)
|
||||
|
||||
|
|
@ -198,14 +210,27 @@ Check whether that typeid has a sheet in `assets/template/template.xlsx`.
|
|||
|
||||
Read every parameter the datasheet actually states into that typeid's columns, converting to
|
||||
each header's unit. **Leave blanks where the datasheet is silent — an honest blank beats a
|
||||
guess.** Collect them into a small `part.json`:
|
||||
guess.**
|
||||
|
||||
The **`Description`** column is special: it is **not** free prose but a strict `_`-joined
|
||||
engineering string — a type prefix, the defining parameters in a fixed order, package near the
|
||||
end, optional AEC-Q last (e.g. `CHIP_RES_36kΩ_62.2mW_±0.1%_0402`, `CHIP_CAP_2.2uF_100v_±10%_1210_x7r`,
|
||||
`SCH_100V_0.25A_SOD-323F`). `references/description_format.md` defines the format for **every**
|
||||
type in the library: the four the Altium SOP spells out (Resistor, Capacitor, Zener, TVS) are
|
||||
**strict**; the rest are the house extension on the same basis. Look up the part's type there,
|
||||
build the Description to that format, and if a real datasheet doesn't fit the format cleanly,
|
||||
follow the pattern and **flag the mismatch to the engineer** rather than bending it silently.
|
||||
Collect the values into a small `part.json`:
|
||||
|
||||
```json
|
||||
{"mpn":"BAT46WJ","manufacturer":"Nexperia","typeid":"SCH",
|
||||
"values":{"Description":"100 V 250 mA Schottky, SOD323F","Forward Voltage(V)":"0.71",
|
||||
"Reverse Voltage(V)":"100","Forward Current(A)":"0.25","Package":"SOD323F"}}
|
||||
"values":{"Description":"SCH_100V_0.25A_SOD-323F","Forward Voltage(V)":"0.71",
|
||||
"Reverse Voltage(V)":"100","Forward Current(A)":"0.25","Package":"SOD-323F"}}
|
||||
```
|
||||
|
||||
(typeid `SCH` → prefix `SCH`, format `SCH_Vr_Io_Package`, so a 100 V / 250 mA Schottky in
|
||||
SOD-323F becomes `SCH_100V_0.25A_SOD-323F`.)
|
||||
|
||||
```bash
|
||||
python scripts/fill_templates.py part.json \
|
||||
--template assets/template/template.xlsx --dest <stage>/<tag>/
|
||||
|
|
@ -334,6 +359,80 @@ and tell the user the previous sheets were updated:
|
|||
python scripts/gitea_components.py commit-push --root work/ --message "backfill <param> into <typeid>"
|
||||
```
|
||||
|
||||
## Updating an existing part
|
||||
|
||||
When the duplicate check finds the part (or the user asks to revise one that's already in
|
||||
Gitea), you're **editing a part in place** rather than assembling a new one. The mechanics are
|
||||
the same edit-in-a-checkout pattern as backfill — the difference is you're changing one part's
|
||||
own data, not applying a template change across a whole typeid. The guiding rule doesn't
|
||||
change: nothing is overwritten until the engineer has verified the new version.
|
||||
|
||||
1. **Locate the part in a checkout you can commit.** Clone the library repo, then find the
|
||||
part's folder and typeid (recovered from its tag):
|
||||
|
||||
```bash
|
||||
python scripts/gitea_components.py checkout --dest work/
|
||||
python scripts/gitea_components.py find-part --mpn <MPN> --make <make> --root work/ --json
|
||||
```
|
||||
|
||||
`find-part` returns the part's Class, tag, typeid, the editable folder path under `work/`,
|
||||
and the files in it (its current `<tag>.xlsx`, datasheet, symbol, footprint). If it prints
|
||||
`NOT FOUND` (exit 4), the part isn't actually there — treat it as a **new** part and go back
|
||||
to the normal add flow from step 2.
|
||||
|
||||
2. **Decide with the user what's changing.** A part update can revise any of: the **parameter
|
||||
values** (re-read the datasheet, or a corrected/newer one), the **symbol/footprint**, or the
|
||||
**datasheet PDF** itself. Ask which, so you only touch what's meant to change and leave the
|
||||
rest of the folder intact.
|
||||
|
||||
3. **Apply the change in place, in `work/<Class>/<tag>/`.** A key thing to understand first:
|
||||
`fill_templates` **rewrites the whole data row**, so it fills the four design columns
|
||||
(`Library Ref/Path`, `Footprint Ref/Path`) from the `--design` map you give it — and leaves
|
||||
them **blank if you don't**. When you rebuild a sheet, always re-supply the design values, or
|
||||
you'll silently wipe the symbol/footprint refs that were already there. The symbol and
|
||||
footprint files live in the part folder, so re-deriving them is cheap: point `altium_refs`
|
||||
at whatever the folder will hold **after** your change.
|
||||
|
||||
- **Values** (re-read the datasheet, or a corrected/newer one) → read the current
|
||||
`<tag>.xlsx` and the folder's datasheet so you start from what's there, re-extract into a
|
||||
fresh `part.json` (Description still built to `references/description_format.md`),
|
||||
re-derive the design columns from the folder's existing symbol/footprint, and rebuild the
|
||||
sheet in place **with `--design`**:
|
||||
|
||||
```bash
|
||||
python scripts/altium_refs.py design \
|
||||
--symbol work/<Class>/<tag>/<symbol>.SchLib \
|
||||
--footprint work/<Class>/<tag>/<footprint>.PcbLib > design.json
|
||||
python scripts/fill_templates.py part.json \
|
||||
--template assets/template/template.xlsx --dest work/<Class>/<tag>/ --design design.json
|
||||
```
|
||||
|
||||
Because `fill_templates` reads the **current** template and versions, the rebuilt sheet
|
||||
keeps this typeid's version stamp (a part-data fix isn't a template change, so nothing
|
||||
bumps) and picks up any columns the typeid has gained — while the `--design` map carries
|
||||
the existing symbol/footprint refs through unchanged. (If a part somehow has no
|
||||
symbol/footprint yet, there's nothing to preserve — rebuild without `--design`.)
|
||||
- **Symbol/footprint** → copy the new `.SchLib`/`.PcbLib` into the folder under their proper
|
||||
names (replacing the old ones), then re-derive against the **new** files and rebuild with
|
||||
`--design` exactly as above (this is step 6 of the add flow). Still flag a genuine
|
||||
symbol/footprint-vs-part mismatch — that's a correctness issue.
|
||||
- **Datasheet** → drop the newer PDF in as `<MPN>_data.<ext>`, replacing the old one. If the
|
||||
values should reflect it, also redo the values step above.
|
||||
|
||||
4. **Verify, then push.** Hand the rebuilt `<tag>.xlsx` back and run the same human
|
||||
verification loop (step 5) — the engineer is still the ground truth. Once confirmed, commit
|
||||
the checkout and push (attributed to the operator, with a message that says it's an update):
|
||||
|
||||
```bash
|
||||
python scripts/gitea_components.py commit-push --root work/ \
|
||||
--message "update <tag>: <what changed> (by <operator name>)" \
|
||||
--author "<operator name> <<operator email>>"
|
||||
```
|
||||
|
||||
The authored commit and message are the record of the revision (visible in `git log`, the
|
||||
Gitea commit view and `git blame`); the changelog stays reserved for template/version
|
||||
changes, not per-part data fixes. Tell the user what changed and where it landed.
|
||||
|
||||
## Pushing the skill repo
|
||||
|
||||
When skill files change (a new typeid template, a parameter add, a version/changelog bump),
|
||||
|
|
@ -359,6 +458,10 @@ plain flat push, but it does not merge the changelog or blank the token, so pref
|
|||
`MPN_make_type` / `Skill Version` / `Template Version`; `Library Ref/Path`,
|
||||
`Footprint Ref/Path` and `Manufacturer` sit near the end.
|
||||
- `assets/template/Type_ID.xlsx` + `references/taxonomy.md` — Class → Subclass → Type ID.
|
||||
- `references/description_format.md` — Vecmocon's Altium **Description Format** (the `_`-joined
|
||||
engineering string for each part's Description column). Defines a format for **every** type:
|
||||
the four SOP-defined ones (RES/CAP/Zener/TVS) are strict, the rest are the house extension on
|
||||
the same basis. Read it before filling any Description.
|
||||
- `assets/template/versions.json` — per-typeid `template_version` + `skill_version`.
|
||||
- `assets/CHANGELOG.xlsx` — global version/parameter changelog (created on first add;
|
||||
merged into the skill repo's copy in Gitea by `push-skill`).
|
||||
|
|
@ -369,9 +472,9 @@ plain flat push, but it does not merge the changelog or blank the token, so pref
|
|||
- `scripts/append_parameter.py` — append parameter(s) to a typeid, bump its versions, write
|
||||
the changelog.
|
||||
- `scripts/altium_refs.py` — read Library/Footprint Ref from `.SchLib`/`.PcbLib`.
|
||||
- `scripts/gitea_components.py` — `check-mpn`, `checkout`, `list-type`, `place-part`,
|
||||
`commit-push`, `push-part` (library repo), and `push-skill` (skill repo: token-blanked
|
||||
push + append-only changelog merge).
|
||||
- `scripts/gitea_components.py` — `check-mpn`, `find-part` (locate an existing part to
|
||||
update), `checkout`, `list-type`, `place-part`, `commit-push`, `push-part` (library repo),
|
||||
and `push-skill` (skill repo: token-blanked push + append-only changelog merge).
|
||||
- `scripts/push_to_gitea.sh` — push a folder's contents to a Gitea repo (used for the skill
|
||||
repo).
|
||||
- `config/gitea.env` — host, user, token, and the `SKILL_REPO` / `LIBRARY_REPO` names
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -3,7 +3,7 @@
|
|||
# Use a token scoped to these repos (repository: write) and rotate periodically.
|
||||
GIT_HOST=gitea.vecmocon.com
|
||||
GIT_USER=nitishKumar
|
||||
GIT_TOKEN=451bff1dc32202cbc0a371f8e5645079466d2120
|
||||
GIT_TOKEN=
|
||||
# Target repos — TWO now (set these to the exact repo names on your Gitea):
|
||||
# SKILL_REPO : holds this skill's own files (SKILL.md, scripts, assets, ...).
|
||||
# LIBRARY_REPO : holds components, one folder per Class (Diode, IC, ...); inside each,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"skill_name": "library-manager",
|
||||
"evals": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "resistor-description-format",
|
||||
"prompt": "We're adding the Yageo RC0402FR-0736KL to our component library. From its datasheet: resistance 36 kohm, tolerance 1%, package 0402, rated power 63 mW (1/16 W), thick-film chip resistor, not AEC-Q qualified. Following our library process, what exactly should go in this part's Description field in its library sheet? Give me the final Description string.",
|
||||
"expected_output": "A strict SOP Description string (e.g. CHIP_RES_36kOhm_63mW_+-1%_0402): type prefix, value, wattage, tolerance, package; no AEC-Q token since not qualified. NOT free prose.",
|
||||
"files": []
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "capacitor-description-format",
|
||||
"prompt": "Adding a TDK CGA5L1X7R2A225K MLCC to the library. Datasheet: 2.2 uF, 100 V, tolerance 10%, 1210 case size, X7R dielectric, AEC-Q200 qualified. Per our library workflow, what is the exact Description field value for this part?",
|
||||
"expected_output": "A strict SOP Description string (e.g. CHIP_CAP_2.2uF_100v_+-10%_1210_x7r_AECQ-200): type, value, voltage, tolerance, package, temp-coefficient, AEC-Q last. NOT free prose.",
|
||||
"files": []
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "existing-part-update-flow",
|
||||
"prompt": "The part BAT46WJ from Nexperia is already in our library, but its forward-voltage value was entered wrong. I want to correct it. Walk me through exactly how you'd handle this with our library tooling, including the commands you'd run.",
|
||||
"expected_output": "Recognizes this is an UPDATE of an existing part (not a hard-stop): offers update-or-stop, uses checkout + find-part to locate it, rebuilds the sheet in place with fill_templates (no version bump), keeps human verification, then commit-push with operator attribution. Does not invent a delete/re-add.",
|
||||
"files": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
# Description format (Vecmocon Altium Library SOP)
|
||||
|
||||
This is the authoritative rule for the **Description** field the skill writes into a part's
|
||||
workbook. It has two layers:
|
||||
|
||||
1. The **four formats the SOP defines outright** — Resistor, Capacitor, Zener, TVS — from
|
||||
*Engineering Data Management — SOP: Component Naming, Mandatory Parameters, and Design Item
|
||||
ID Format* (§6). Follow these parameter orders **strictly** (with one house tweak: the
|
||||
Zener/TVS prefix uses the generic diode code `ZEN`/`TVS`, not the SOP's `DIO-Z`/`DIO-T` — see
|
||||
the note under those two below).
|
||||
2. A **house extension** that carries the *same basis* to every other type in the library
|
||||
(all 125 type-IDs / 18 classes), so no component is left without a Description convention.
|
||||
These are built on the SOP pattern and are the working standard; when a specific part
|
||||
doesn't fit cleanly, follow the pattern and confirm the token order with the engineer rather
|
||||
than inventing something off-pattern.
|
||||
|
||||
## The basis (applies to every component)
|
||||
|
||||
The Description is **not** a free-form sentence. It is a single string of `_`-joined tokens in
|
||||
this shape:
|
||||
|
||||
```
|
||||
PREFIX_param1_param2_..._Package_[AECQ-XXX]
|
||||
```
|
||||
|
||||
- **PREFIX** — a short token (or two) naming the sub-family / technology, e.g. `CHIP_RES`,
|
||||
`ELE_CAP`, `SCH`, `NMOS`. The per-type prefix is listed for every type below.
|
||||
- **params** — the part's defining ratings, in the **fixed order** given for that class. Read
|
||||
them off the datasheet. If the datasheet is silent on a required token, leave it out and flag
|
||||
it — an honest gap beats a guessed value.
|
||||
- **Package** — the IPC/industry package or case code, near the end (`0402`, `SOD-323`,
|
||||
`SOIC-8`, `LQFP-48`, `SMD,D6.3xL5.8mm`, …).
|
||||
- **AECQ-XXX** — only when the datasheet states automotive qualification (`AECQ-200`,
|
||||
`AECQ-101`, `AECQ-100`); it is always the **last** token. Omit entirely if not stated —
|
||||
never assume qualification.
|
||||
|
||||
Description ≠ Design Item ID ≠ Comment — three different fields that share notation but not
|
||||
content: **Description** is the strict string here (SOP §6); **Design Item ID** (SOP §2) is a
|
||||
shorter procurement id (`RES_36kΩ_±0.1%_0402`) — use it only as a guide to token vocabulary,
|
||||
never put it in the Description column; **Comment** (SOP §4) is always the exact MPN.
|
||||
|
||||
## Notation conventions (from the SOP examples)
|
||||
|
||||
- **Value / unit** with SOP casing: `36kΩ`, `2.2uF`, `600Ω`, `48MHz`, `10uH`. Use `Ω` for ohms;
|
||||
`uF`/`nF`/`pF`, `uH`/`nH`/`mH`, `Hz`/`kHz`/`MHz`, `F` for farads (supercaps). A **range** uses
|
||||
`~` (`3.5V~28V`, `5.2V~5.6V`).
|
||||
- **Power** `62.2mW`, `500mW`, `344W`; **voltage** `100v`, `25V`; **current** `0.25A`, `250mA`.
|
||||
- **Tolerance** signed percent `±0.1%`, `±10%`.
|
||||
- **Temperature coefficient** (ceramics) lower-case dielectric class: `x7r`, `c0g`, `x5r`.
|
||||
- Keep tokens in the same style throughout so descriptions sort and read consistently.
|
||||
|
||||
---
|
||||
|
||||
# Layer 1 — the four SOP-defined formats (strict)
|
||||
|
||||
**Resistor**
|
||||
|
||||
```
|
||||
Type_RES_Value_Wattage_Tolerance_Package_AECQ-XXX(optional)
|
||||
```
|
||||
|
||||
Example: `CHIP_RES_36kΩ_62.2mW_±0.1%_0402`
|
||||
|
||||
**Capacitor**
|
||||
|
||||
```
|
||||
Type_CAP_Value_Voltage_Tolerance_Package_TemperatureCoefficient_AECQ-XXX(optional)
|
||||
```
|
||||
|
||||
Example: `CHIP_CAP_2.2uF_100v_±10%_1210_x7r`
|
||||
|
||||
**Zener diode**
|
||||
|
||||
```
|
||||
ZEN_VoltageZener(Vz)_Power_Package_AECQ-XXX(optional)
|
||||
```
|
||||
|
||||
**TVS diode**
|
||||
|
||||
```
|
||||
TVS_VoltageBreakdown(Vbr)_VoltageClamping(Vc)_Current(Ip)_Package_AECQ-XXX(optional)
|
||||
```
|
||||
|
||||
**House prefix note:** the SOP §6 wrote these two as `DIO-Z` / `DIO-T`, but Vecmocon
|
||||
standardised on the **generic diode type code** (`ZEN`, `TVS`, and likewise `SCH`, `ESD`, …) as
|
||||
the prefix for *all* diodes. So use `ZEN` / `TVS` here — the parameter order (Vz+Power for
|
||||
Zener; Vbr+Vc+Ip for TVS) is still exactly the SOP's; only the prefix token differs.
|
||||
|
||||
---
|
||||
|
||||
# Layer 2 — house extension, every other type (same basis)
|
||||
|
||||
Each class below gives its **parameter order** (the tokens between prefix and package) and the
|
||||
**per-type prefix**. Package is always the second-to-last token; optional `AECQ-XXX` is last.
|
||||
|
||||
## Resistor (RES family) — `PREFIX_Value_Power_Tolerance_Package_[AECQ]`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| FIX Thick-film chip | `CHIP_RES` | SOP example; the strict format above |
|
||||
| TFR Thin-film chip | `TFILM_RES` | precision/low-tempco; may append tempco (ppm) |
|
||||
| MFR Metal-film | `MFILM_RES` | |
|
||||
| CFR Carbon-film | `CFILM_RES` | |
|
||||
| MOR Metal-oxide | `MOX_RES` | high-power leaded |
|
||||
| WWR Wirewound | `WW_RES` | low-ohm/high-power |
|
||||
| SHT Current-sense/shunt | `SHUNT_RES` | value in mΩ (e.g. `2mΩ`), power token is the sense power |
|
||||
| ARR Array/network | `ARR_RES` | add element count/config, e.g. `4x`, before value |
|
||||
| POT Potentiometer/trimmer | `POT` | `POT_Value_Taper_Power_Package` (taper `LIN`/`LOG`) |
|
||||
| FSR Fusible/safety | `FUSE_RES` | |
|
||||
| NTC thermistor | `NTC` | `NTC_R25_Beta_Tolerance_Package` (R25 e.g. `10kΩ`, Beta e.g. `B3950`) |
|
||||
| PTC thermistor | `PTC` | `PTC_R25_Package` (or trip current/temp if that's the rated spec) |
|
||||
|
||||
Example: `SHUNT_RES_2mΩ_1W_±1%_2512` · `NTC_10kΩ_B3950_±1%_0402`
|
||||
|
||||
## Capacitor (CAP family) — `PREFIX_Value_Voltage_Tolerance_Package_[Dielectric]_[AECQ]`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| CER Ceramic MLCC | `CHIP_CAP` | SOP; dielectric token (`x7r`/`c0g`…) required |
|
||||
| ELE Aluminium electrolytic | `ELE_CAP` | tolerance often omitted; case like `SMD,D6.3xL5.8mm` |
|
||||
| TAN Tantalum | `TANT_CAP` | |
|
||||
| PLY Aluminium-polymer | `POLY_CAP` | low-ESR; ESR may follow voltage |
|
||||
| FLM Film (MKT/MKP) | `FILM_CAP` | |
|
||||
| SFY Safety Class-X/Y | `SAFETY_CAP` | add safety class token (`X2`/`Y1`) after value |
|
||||
| SUP Supercapacitor/EDLC | `SUPERCAP` | value in farads, e.g. `1F`; add ESR if rated |
|
||||
|
||||
Example: `ELE_CAP_33uF_25V_SMD,D6.3xL5.8mm` · `SUPERCAP_1F_5.5V_RADIAL`
|
||||
|
||||
## Inductor / Magnetics — `PREFIX_Value_Current_[DCR]_Package_[AECQ]`
|
||||
|
||||
| Type | Prefix | Format detail |
|
||||
|------|--------|---------------|
|
||||
| PWR Power inductor | `PWR_IND` | `PWR_IND_L_Isat_DCR_Package` (L e.g. `10uH`, Isat `3A`) |
|
||||
| FBD Ferrite bead | `FB` | `FB_Impedance@freq_Current_Package` (e.g. `FB_600Ω@100MHz_2A_0603`) |
|
||||
| CMC Common-mode choke | `CMC` | `CMC_Impedance@freq_Current_Package` |
|
||||
| RFI RFI choke | `RFI_CHK` | `RFI_CHK_L_Current_Package` |
|
||||
| XFM Transformer | `XFMR` | `XFMR_Ratio_Power_Package` (ratio e.g. `1:1`) |
|
||||
| CTX Current transformer | `CT` | `CT_Ratio_Package` (e.g. `1000:1`) |
|
||||
| CPL Coupled inductor | `CPL_IND` | `CPL_IND_L_Current_Package` |
|
||||
|
||||
## Diode — reverse-voltage / current ratings, then package
|
||||
|
||||
The prefix is the **generic diode type code (the typeid itself)** — `REC`, `FRD`, `SCH`, `SIC`,
|
||||
`ZEN`, `TVS`, `ESD`, `SWI`, `BRG`, `LED` — not a `DIO-x` form.
|
||||
|
||||
| Type | Prefix | Format |
|
||||
|------|--------|--------|
|
||||
| REC Rectifier | `REC` | `REC_Vrrm_Io_Package` |
|
||||
| FRD Fast-recovery | `FRD` | `FRD_Vrrm_Io_trr_Package` |
|
||||
| SCH Schottky | `SCH` | `SCH_Vr_Io_Package` |
|
||||
| SIC SiC Schottky | `SIC` | `SIC_Vr_Io_Package` |
|
||||
| ZEN Zener | `ZEN` | `ZEN_Vz_Power_Package` |
|
||||
| TVS TVS | `TVS` | `TVS_Vbr_Vc_Ip_Package` |
|
||||
| ESD ESD protection | `ESD` | `ESD_Vrwm_Vc_Channels_Package` |
|
||||
| SWI Switching/small-signal | `SWI` | `SWI_Vr_Io_trr_Package` |
|
||||
| BRG Bridge rectifier | `BRG` | `BRG_Vrrm_Io_Package` |
|
||||
| LED Indicator LED | `LED` | `LED_Color_Vf_If_Package` (color e.g. `RED`) |
|
||||
|
||||
Example (Schottky BAT46WJ, 100 V / 250 mA): `SCH_100V_0.25A_SOD-323F`
|
||||
|
||||
## Transistor — `PREFIX_Voltage_Current_[Rds(on)]_Package_[AECQ]`
|
||||
|
||||
The polarity/channel is **folded into the prefix** as a single token (matching the SOP's own
|
||||
Design Item ID form, e.g. `NMOS_20V_SOT-23`), not carried as a separate `_NCH`/`_PCH` token.
|
||||
|
||||
| Type | Prefix | Format |
|
||||
|------|--------|--------|
|
||||
| BJT BJT | `BJT_NPN` / `BJT_PNP` | `BJT_NPN_Vceo_Ic_Package` |
|
||||
| MOS MOSFET (Si) | `NMOS` / `PMOS` | `NMOS_Vds_Id_Rdson_Package` |
|
||||
| SCM SiC MOSFET | `NSICFET` / `PSICFET` | `NSICFET_Vds_Id_Rdson_Package` |
|
||||
| GAN GaN FET | `GANFET` | `GANFET_Vds_Id_Rdson_Package` |
|
||||
| IGBT IGBT | `IGBT` | `IGBT_Vces_Ic_Package` |
|
||||
| JFET JFET | `NJFET` / `PJFET` | `NJFET_Vds_Idss_Package` |
|
||||
| DIG Digital/bias-R transistor | `DTR_NPN` / `DTR_PNP` | `DTR_NPN_Vceo_R1/R2_Package` |
|
||||
|
||||
Example: `NMOS_20V_6A_15mΩ_SOT-23` · `BJT_NPN_50V_0.1A_SOT-416FL`
|
||||
|
||||
## Integrated Circuit (IC) — one line per subtype; package always last (before AECQ)
|
||||
|
||||
| Type | Prefix | Format |
|
||||
|------|--------|--------|
|
||||
| MCU Microcontroller | `MCU` | `MCU_Core_Flash_Package` (e.g. `MCU_M0+_128Kb_LQFP-48`) |
|
||||
| LDO LDO regulator | `LDO` | `LDO_Vout_Iout_Package` (`ADJ` if adjustable) |
|
||||
| DCD DC-DC IC | `DCD` | `DCD_Topology_Vin_Iout_Package` (topology `BUCK`/`BOOST`/`BUCKBOOST`) |
|
||||
| PMU PMIC | `PMIC` | `PMIC_Rails_Package` |
|
||||
| BMS BMS AFE | `BMS` | `BMS_Cells_Package` (e.g. `16S`) |
|
||||
| DRV Gate/motor driver | `DRV` | `DRV_Type_Voltage_Current_Package` (type `GATE`/`MOTOR`/`HB`) |
|
||||
| AMP Amplifier/op-amp | `AMP` | `AMP_GBW_Channels_Package` |
|
||||
| CMP Comparator | `CMP` | `CMP_Channels_Package` |
|
||||
| VRF Voltage reference | `VREF` | `VREF_Voltage_Tolerance_Package` |
|
||||
| ADC ADC | `ADC` | `ADC_Bits_Rate_Package` |
|
||||
| DAC DAC | `DAC` | `DAC_Bits_Channels_Package` |
|
||||
| ISO Isolator/optocoupler | `ISO` | `ISO_Channels_IsolationV_Package` |
|
||||
| XCV Transceiver | `XCVR` | `XCVR_Bus_Speed_Package` (bus `CAN`/`RS485`; e.g. `XCVR_CAN_5Mbps_SOIC-8`) |
|
||||
| AFE Analog front end | `AFE` | `AFE_Function_Package` |
|
||||
| MEM Memory | `MEM` | `MEM_Type_Size_Interface_Package` (e.g. `MEM_FLASH_128Mb_SPI_SOIC-8`) |
|
||||
| LOG Logic gate | `LOG` | `LOG_Function_Package` (e.g. `AND2`, `BUF`) |
|
||||
| SEN Sensor IC | `SEN_IC` | `SEN_IC_Type_Package` |
|
||||
| IFC Interface/expander | `IFC` | `IFC_Function_Package` |
|
||||
| CLK Clock/RTC | `CLK` | `CLK_Freq_Package` (or `RTC_Package`) |
|
||||
| SVR Supervisor/reset | `SVR` | `SVR_Threshold_Package` |
|
||||
| MTR Energy metering | `METER` | `METER_Phases_Package` |
|
||||
|
||||
## Protection Device — `PREFIX_ratings_Package`
|
||||
|
||||
| Type | Prefix | Format |
|
||||
|------|--------|--------|
|
||||
| FUS Fuse | `FUSE` | `FUSE_Current_Voltage_Package` (speed `F`/`T` may precede current) |
|
||||
| RSF Resettable/PPTC | `PPTC` | `PPTC_Ihold_Voltage_Package` |
|
||||
| VAR Varistor/MOV | `MOV` | `MOV_Vrms_Energy_Package` |
|
||||
| GDT Gas-discharge tube | `GDT` | `GDT_Vspark_Package` |
|
||||
| CBK Circuit breaker | `BREAKER` | `BREAKER_Current_Poles_Package` |
|
||||
|
||||
## Power Conversion Module — `PREFIX_Vin_Vout_Power_Package`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| DCM DC-DC module | `DCM` | non-isolated PoL |
|
||||
| IDC Isolated DC-DC | `IDCM` | isolated brick |
|
||||
| INV Inverter (DC-AC) | `INV` | `INV_Power_Voltage_Package` |
|
||||
| OBC On-board charger | `OBC` | `OBC_Power_Voltage_Package` |
|
||||
| CHG Charger module | `CHG` | `CHG_Power_Voltage_Package` |
|
||||
| PSU AC-DC SMPS | `PSU` | `PSU_Power_Vout_Package` |
|
||||
| RCM Rectifier module | `RECT` | `RECT_Current_Voltage_Package` |
|
||||
|
||||
## Relay / Contactor — `PREFIX_CoilVoltage_ContactRating_Package`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| RLS Signal relay | `RLY_S` | contact rating e.g. `2A/30V` |
|
||||
| RLP Power relay | `RLY_P` | |
|
||||
| SSR Solid-state relay | `SSR` | `SSR_ControlV_LoadRating_Package` |
|
||||
| RLR Reed relay | `RLY_REED` | |
|
||||
| CTC Contactor | `CTC` | HV/HC contact rating |
|
||||
|
||||
## Switch / Button — `PREFIX_[Positions]_Rating_Package`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| SWT Tactile | `SW_TACT` | rating e.g. `50mA/12V` |
|
||||
| PBT Push button | `SW_PB` | |
|
||||
| DSW DIP/slide | `SW_DIP` | positions e.g. `4P` |
|
||||
| RSW Rocker/toggle | `SW_ROCK` | |
|
||||
| RSY Rotary | `SW_ROT` | positions e.g. `12POS` |
|
||||
|
||||
## Connector — `CON_TYPE_Positions_Pitch_Package`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| CWB Wire-to-board | `CON_W2B` | e.g. `CON_W2B_2x2_P2.0` |
|
||||
| CBB Board-to-board | `CON_B2B` | |
|
||||
| HDR Header/socket | `CON_HDR` | pitch e.g. `2.54mm` |
|
||||
| FFC FFC/FPC | `CON_FFC` | |
|
||||
| USB USB/data | `CON_USB` | add USB type (`C`, `MICRO`) |
|
||||
| PWC Power/high-current | `CON_PWR` | add current rating |
|
||||
| TBK Terminal block | `CON_TB` | |
|
||||
|
||||
## Antenna / RF — `PREFIX_Band_Package`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| ANC Chip antenna | `ANT_CHIP` | band e.g. `2.4GHz` |
|
||||
| ANP PCB/trace antenna | `ANT_PCB` | |
|
||||
| ANE External/whip | `ANT_EXT` | add connector token |
|
||||
| SAW SAW filter | `SAW` | `SAW_Freq_Package` |
|
||||
| RFM RF/wireless module | `RFMOD` | protocol e.g. `BLE`, `WIFI`, `LTE` |
|
||||
|
||||
## Crystal / Oscillator / Timing — `PREFIX_Freq_[Load]_Package`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| XTL Crystal | `XTAL` | `XTAL_Freq_LoadCap_Package` (e.g. `XTAL_48MHz_18pF_SMD2016-4P`) |
|
||||
| OSC Crystal oscillator | `OSC` | `OSC_Freq_Package` |
|
||||
| MMO MEMS oscillator | `MEMS_OSC` | |
|
||||
| RSN Ceramic resonator | `RESON` | `RESON_Freq_Package` |
|
||||
|
||||
## Battery / Cell — `PREFIX_Capacity_Voltage_Format`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| CLI Li-ion cell | `CELL_LI` | format e.g. `18650`; capacity `2600mAh` |
|
||||
| CLF LiFePO4 cell | `CELL_LFP` | |
|
||||
| CCO Coin/button | `CELL_COIN` | add chemistry (`CR`/`LIR`) + size (`2032`) |
|
||||
| CNI NiMH | `CELL_NIMH` | |
|
||||
| BPK Battery pack | `PACK` | `PACK_Voltage_Capacity` (e.g. `48V_20Ah`) |
|
||||
| CHL Cell holder | `HOLDER` | `HOLDER_CellType_Package` |
|
||||
|
||||
## Audible / Indicator
|
||||
|
||||
| Type | Prefix | Format |
|
||||
|------|--------|--------|
|
||||
| BUZ Magnetic buzzer | `BUZ_MAG` | `BUZ_MAG_Voltage_Freq_Package` |
|
||||
| PBZ Piezo buzzer | `BUZ_PIEZO` | `BUZ_PIEZO_Voltage_Freq_Package` |
|
||||
| SPK Speaker | `SPK` | `SPK_Power_Impedance_Package` |
|
||||
| IND Indicator lamp | `IND` | `IND_Color_Voltage_Package` |
|
||||
|
||||
## Display / HMI — `PREFIX_Resolution/Digits_Size_Interface`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| DSG 7-segment | `DISP_7SEG` | `DISP_7SEG_Digits_Color_Package` |
|
||||
| OLE OLED | `DISP_OLED` | resolution e.g. `128x64`, size `0.96in` |
|
||||
| LCD LCD | `DISP_LCD` | char (`16x2`) or graphic resolution |
|
||||
| TFT TFT | `DISP_TFT` | resolution + size + interface (`SPI`/`RGB`) |
|
||||
|
||||
## Sensor (discrete / module) — `SEN_TYPE_Range_[Interface]_Package`
|
||||
|
||||
| Type | Prefix | Notes |
|
||||
|------|--------|-------|
|
||||
| STE Temperature | `SEN_TEMP` | range + interface (`I2C`/`ANALOG`) |
|
||||
| SCU Current (Hall) | `SEN_CURR` | range e.g. `±50A` |
|
||||
| SVO Voltage/isolated | `SEN_VOLT` | |
|
||||
| SHA Hall/position | `SEN_HALL` | type (`LATCH`/`LINEAR`) |
|
||||
| SIM IMU/accel | `SEN_IMU` | axes (`6AXIS`) + interface |
|
||||
| SPR Pressure | `SEN_PRES` | range + interface |
|
||||
|
||||
## Thermal / Cooling
|
||||
|
||||
| Type | Prefix | Format |
|
||||
|------|--------|--------|
|
||||
| FAN Fan | `FAN` | `FAN_Size_Voltage_Airflow` (size e.g. `40x40mm`) |
|
||||
| HSK Heatsink | `HSK` | `HSK_Dimensions_ThermalResistance` |
|
||||
| TPD Thermal pad/TIM | `TIM` | `TIM_Conductivity_Thickness` |
|
||||
|
||||
---
|
||||
|
||||
## When a part doesn't fit
|
||||
|
||||
The Layer-2 formats are the working house standard, but real datasheets vary. If a part is
|
||||
missing a token the format asks for, leave it out and flag it. If it has a defining rating the
|
||||
format doesn't capture, add it in the sensible position and **tell the engineer** what you
|
||||
added so the convention can be updated deliberately. Never silently bend a format — an
|
||||
inconsistent Description is worse than one confirmed question. The Layer-1 (SOP) formats are
|
||||
fixed and are not up for reinterpretation.
|
||||
|
|
@ -15,6 +15,13 @@ testing or offline work):
|
|||
early duplicate gate, run BEFORE classifying.) Prints EXISTS/<tag> or ABSENT; exit 0
|
||||
if absent, 3 if it already exists (so a shell can hard-stop).
|
||||
|
||||
find-part --mpn BAT46WJ --make Nexperia [--root work/] [--json]
|
||||
Locate an existing part so it can be REVISED (the update path — the mirror of
|
||||
check-mpn, which gates *new* parts). Reports the part's Class, tag, typeid and the
|
||||
files in its folder. Point --root at a `checkout` clone and the folder it returns is
|
||||
the real, editable one to change in place before `commit-push`. Exit 0 if found, 4 if
|
||||
not (so a shell can branch: found -> update, not found -> fall through to add).
|
||||
|
||||
checkout --dest work/
|
||||
Clone the library repo to a working dir you can browse and edit in place.
|
||||
|
||||
|
|
@ -142,6 +149,12 @@ def find_part_dirs(root, prefix="", typeid=None):
|
|||
yield cls, name, pdir
|
||||
|
||||
|
||||
def _typeid_of(tag):
|
||||
"""Recover the typeid from a part tag <MPN>_<make>_<typeid>. The typeid is the last
|
||||
underscore-delimited token, so this is robust even if the MPN itself contains underscores."""
|
||||
return tag.rsplit("_", 1)[1] if "_" in tag else ""
|
||||
|
||||
|
||||
def cmd_check_mpn(env, args):
|
||||
root, _ = _root(env, args)
|
||||
prefix = mpn_make_prefix(args.mpn, args.make)
|
||||
|
|
@ -153,6 +166,31 @@ def cmd_check_mpn(env, args):
|
|||
print("ABSENT")
|
||||
|
||||
|
||||
def cmd_find_part(env, args):
|
||||
"""Locate an existing part by MPN+make so it can be REVISED — the mirror image of
|
||||
check-mpn (which gates *new* parts). Reports the folder, its typeid and its files.
|
||||
|
||||
Point --root at a checkout (from `checkout`) and the folder it returns is the real,
|
||||
editable, committable one — that's the update path: checkout -> find-part -> edit in
|
||||
place -> commit-push. Without --root/--local it clones a throwaway copy for a read-only
|
||||
look. Exit 0 if found, 4 if not (so a shell can branch)."""
|
||||
root, _ = _root(env, args)
|
||||
prefix = mpn_make_prefix(args.mpn, args.make)
|
||||
matches = list(find_part_dirs(root, prefix=prefix))
|
||||
if not matches:
|
||||
print("[]" if args.json else "NOT FOUND")
|
||||
sys.exit(4)
|
||||
out = [{"class": cls, "tag": name, "typeid": _typeid_of(name),
|
||||
"folder": pdir, "files": sorted(os.listdir(pdir))}
|
||||
for cls, name, pdir in matches]
|
||||
if args.json:
|
||||
import json
|
||||
print(json.dumps(out, indent=2))
|
||||
else:
|
||||
for o in out:
|
||||
print(f'{o["class"]}/{o["tag"]} (typeid {o["typeid"]}) -> {", ".join(o["files"])}')
|
||||
|
||||
|
||||
def cmd_checkout(env, args):
|
||||
dest = clone(env, args.dest)
|
||||
print(f"library repo checked out at {dest}")
|
||||
|
|
@ -370,6 +408,10 @@ def main():
|
|||
p = sub.add_parser("check-mpn"); p.add_argument("--mpn", required=True)
|
||||
p.add_argument("--make", required=True); p.add_argument("--local"); p.add_argument("--root")
|
||||
|
||||
p = sub.add_parser("find-part"); p.add_argument("--mpn", required=True)
|
||||
p.add_argument("--make", required=True); p.add_argument("--local"); p.add_argument("--root")
|
||||
p.add_argument("--json", action="store_true")
|
||||
|
||||
p = sub.add_parser("checkout"); p.add_argument("--dest", required=True)
|
||||
|
||||
p = sub.add_parser("list-type"); p.add_argument("--typeid", required=True)
|
||||
|
|
@ -401,14 +443,14 @@ def main():
|
|||
if args.cmd in ("push-skill", "pull-skill"):
|
||||
needs.add("SKILL_REPO")
|
||||
elif args.cmd in ("check-mpn", "checkout", "commit-push", "push-part") or \
|
||||
(args.cmd in ("list-type", "place-part") and not getattr(args, "local", None) and not getattr(args, "root", None)):
|
||||
(args.cmd in ("list-type", "place-part", "find-part") and not getattr(args, "local", None) and not getattr(args, "root", None)):
|
||||
needs.add("LIBRARY_REPO")
|
||||
for k in sorted(needs):
|
||||
if not env.get(k):
|
||||
sys.exit(f"missing {k} in env/config")
|
||||
{"check-mpn": cmd_check_mpn, "checkout": cmd_checkout, "list-type": cmd_list_type,
|
||||
"place-part": cmd_place_part, "commit-push": cmd_commit_push, "push-part": cmd_push_part,
|
||||
"push-skill": cmd_push_skill, "pull-skill": cmd_pull_skill}[args.cmd](env, args)
|
||||
{"check-mpn": cmd_check_mpn, "find-part": cmd_find_part, "checkout": cmd_checkout,
|
||||
"list-type": cmd_list_type, "place-part": cmd_place_part, "commit-push": cmd_commit_push,
|
||||
"push-part": cmd_push_part, "push-skill": cmd_push_skill, "pull-skill": cmd_pull_skill}[args.cmd](env, args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Reference in New Issue