schlib_write: write ComponentDescription alongside SOP parameters (by admin)

main
admin 2026-07-17 08:51:19 +00:00
parent 3e5f756916
commit e460f2d085
16 changed files with 330 additions and 240 deletions

128
SKILL.md Executable file → Normal file
View File

@ -2,15 +2,16 @@
name: library-manager
description: >-
Manage Vecmocon's component library. Extract parameters from a component datasheet PDF into the
per-typeid Excel template. Checks Gitea for a duplicate MPN_make, classifies to a typeid, updates that typeid's template (versioning, changelog, backfill), fills
a per-part workbook with human verification, reads the Altium symbol/footprint refs, assembles
a part folder and pushes to Gitea. Can UPDATE an existing part instead of hard-stopping, and can
WRITE the mandatory SOP parameters directly into a .SchLib symbol while stripping Ultra-Librarian
defaults. On the .SchLib task it also fills that component's Excel (Description + all parameters)
and pushes the updated symbol to Gitea, no verification loop. Descriptions
follow Vecmocon's strict Altium Description Format. Use whenever the user uploads a datasheet,
builds/updates a library entry, adds a template parameter, fills/updates .SchLib parameters, or
pushes a part to Gitea. Always trigger on "\datasheet", "\library", "\library-manager", "\schlib".
per-typeid Excel template. Checks Gitea for a duplicate MPN_make, classifies to a typeid, updates
that typeid's template (versioning, changelog, backfill), fills a per-part workbook with human
verification, reads the Altium symbol/footprint refs, assembles a part folder and pushes to Gitea.
Can UPDATE an existing part instead of hard-stopping. ALWAYS WRITES the mandatory SOP parameters
into the .SchLib symbol (stripping Ultra-Librarian defaults) as a required step of every run
involving a symbol — never asks first. On the .SchLib task it also fills that component's Excel
and pushes, no verification loop. Descriptions follow Vecmocon's strict Altium Description Format.
Use whenever the user uploads a datasheet, builds/updates a library entry, adds a template
parameter, fills/updates .SchLib parameters, or pushes a part to Gitea. Always trigger on
"\datasheet", "\library", "\library-manager", "\schlib".
---
# Library Manager
@ -41,15 +42,18 @@ own, without asking for confirmation**. Never add a "shall I push?" step — jus
the user where it landed. (You still flag a genuine symbol/footprint mismatch, because that's a
correctness issue, not a push confirmation.)
**Symbol parameters are a second exception — stamp them without asking, every time.** This
holds in both directions. As a standalone task (the engineer hands over a `.SchLib`): fill that
component's Excel (Description + all parameters) and push the updated symbol automatically,
without pausing to confirm the values. And **inside the normal new-part flow**: once the symbol
is uploaded at step 6, stamp the SOP + sheet parameters onto it and strip the Ultra-Librarian
defaults as a matter of course — do **not** offer it as a follow-up, do **not** ask whether the
engineer wants it, and never push a part folder whose symbol still carries UL defaults. See
*Mandatory symbol parameters* for why this path skips the loop. Every other flow keeps the
normal interactive asks below.
**The `.SchLib` task is a second exception — it fills and pushes without a verification loop.**
When the engineer hands over a symbol for the schlib flow, fill that component's Excel
(Description + all parameters) and push the updated symbol automatically, without pausing to
confirm the values. See *Mandatory symbol parameters* for why this path skips the loop.
**Writing symbol parameters is a third exception — always do it, never ask.** Whenever a
`.SchLib` is in play — the standalone schlib task *or* step 6b of a new-part run — filling its
mandatory SOP parameters is a required action, not an offer. Never ask "should I fill the symbol
parameters?" or leave it as a suggested next step; the answer is always yes, so just write them
and report it. A symbol that still holds Ultra-Librarian defaults is an incomplete part.
Every other flow keeps the normal interactive asks below.
## Inputs
@ -218,23 +222,32 @@ each header's unit. **Leave blanks where the datasheet is silent — an honest b
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,
engineering string. It **always opens with `Class_TYPEID`** — the part's library Class exactly as
spelled in its repo folder, then its Type ID in upper case — followed by the defining parameters
in a fixed order, package near the end, optional AEC-Q last. E.g.
`Resistor_FIX_36kΩ_62.2mW_±0.1%_0402`, `Capacitor_CER_2.2uF_100v_±10%_1210_x7r`,
`Diode_SCH_100V_0.25A_SOD-323F`, `Diode_TVS_5V_9.2V_18A_SOD-323`.
This `Class_TYPEID` opening is **mandatory for every part, with no exceptions** — including
Resistor, Capacitor, Zener and TVS, where it deliberately overrides the prefix given in SOP §6.
The old technology prefixes (`CHIP_RES`, `CHIP_CAP`, `TANT_CAP`, `NMOS`, `ZEN`, …) are
**retired** — never emit them. `references/description_format.md` defines the parameter order
for **every** type in the library and is authoritative; read it before writing a Description.
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":"SCH_100V_0.25A_SOD-323F","Forward Voltage(V)":"0.71",
"values":{"Description":"Diode_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`.)
(typeid `SCH` sits in Class `Diode` → prefix `Diode_SCH`, format `Diode_SCH_Vr_Io_Package`, so a
100 V / 250 mA Schottky in SOD-323F becomes `Diode_SCH_100V_0.25A_SOD-323F`. The Class token is
the repo folder name from `CLASS_FOLDER` in `scripts/common.py`, so the Description's first token
always matches the folder the part is pushed to.)
```bash
python scripts/fill_templates.py part.json \
@ -297,33 +310,40 @@ python scripts/fill_templates.py part.json \
--template assets/template/template.xlsx --dest <stage>/<tag>/ --design design.json
```
Once you have the symbol and its Library Ref, **stamp the mandatory symbol parameters onto the
`.SchLib` — always, automatically, without asking.** This is not an optional extra and it is not
something to offer the engineer: a symbol that reaches Gitea carrying Ultra-Librarian defaults
instead of the SOP set is an incomplete part. Do it in this same run, before step 7, so the
folder is pushed complete the first time.
### 6b. Write the mandatory symbol parameters — always, without asking
Build the parameter set from the datasheet values you already read for the workbook (they are the
same values — Manufacturer, Manufacturer Part, Value, Tolerance, Operating Temperature, RoHS,
Datasheet, Process, Vecmocon Part Code, …), **plus every engineering parameter from this typeid's
sheet** and `Component Type` = the part's Class, then write them in and strip the UL defaults —
see *Mandatory symbol parameters* below for the full set and the exact commands. Skip only the
housekeeping columns (`MPN_make_type`, Skill/Template Version) and the four Library/Footprint
Ref/Path columns — those are Altium's own model links, so duplicating them as parameters would
create two sources of truth.
Once you have the symbol and its Library Ref, **write the mandatory symbol parameters into the
`.SchLib`**. This is **not optional and not a question** — it is a required step of every
new-part run. Do not ask "would you like me to fill the symbol parameters?", do not offer it as
a suggestion, and do not defer it to a later turn. Just do it, then report that it's done.
Don't stop to confirm the values here either; the engineer validates the symbol by opening it in
Altium, which is the real check. Leave genuinely-unknown fields blank (the SOP hides blank
parameters) and **note the gaps in your summary** rather than blocking on a question — the one
field that is never on a datasheet is `Vecmocon Part Code`, so use it if the engineer supplied it
and otherwise leave it blank and say so.
The SOP requires the fixed parameter set (Manufacturer, Manufacturer Part, Value, Tolerance,
Operating Temperature, RoHS, Datasheet, Process, Vecmocon Part Code, …) on every symbol, **plus
the symbol's Description**, so a part folder whose `.SchLib` has not been filled is **incomplete
and must not be pushed**. Build the part's `params.json` from the values the engineer just
verified in step 5 — including `"description"`, set to the **same** strict `Class_TYPEID` string
you put in the part's Excel — and run:
```bash
python scripts/schlib_write.py \
--schlib <stage>/<tag>/<symbol_name>.SchLib \
--params params.json \
--out <stage>/<tag>/<symbol_name>.SchLib
```
See *Mandatory symbol parameters* below for the full parameter set, the value-shorthand rules,
and the Ultra-Librarian default-stripping behaviour — read `references/schlib_parameters.md`
before building the parameter set. The values are already verified at this point, so this step
inherits no verification loop of its own.
### 7. Assemble the part folder
The staging folder `<tag>/` should now hold the four files: the per-part `<tag>.xlsx`, the
datasheet (name it `<MPN>_data.<ext>`), the symbol (the **stamped** one from step 6, not the raw
upload), and the footprint. If the engineer's upload carried extra files (a `.step` 3D model, a
`.LibPkg`), ask whether to include them — the standard folder is these four.
datasheet (name it `<MPN>_data.<ext>`), the symbol, and the footprint.
**Before pushing, check that the symbol has actually been filled** (step 6b). The part folder is
not complete until it has. If the `.SchLib` still carries only Ultra-Librarian defaults, go back
and run `schlib_write.py` — don't push, and don't ask the user whether to; just fill it.
### 8. Push to the library repo, under the part's Class
@ -341,8 +361,15 @@ user where it landed.
The SOP (§5) requires every schematic symbol to carry a fixed parameter set in its Altium
properties — `Component Type`, `Manufacturer`, `Manufacturer Part`, `Value`, `Tolerance`,
`Operating Temperature`, `ROHS`, `Datasheet`, `Process`, `Vecmocon Part Code`, and the two
second-source fields — with the **Comment** set to the MPN. The skill can stamp these onto the
symbol from the datasheet.
second-source fields — with the **Comment** set to the MPN and the **Description** set to the
part's strict `Class_TYPEID` string. The skill stamps all of these onto the symbol from the
datasheet in a single pass.
**Description is written too, always.** It isn't a parameter — it's the `ComponentDescription`
field in the symbol's header, which Ultra-Librarian ships as the placeholder text `Description`.
So it must be written explicitly or the symbol shows the literal word "Description" in Altium
even when every parameter is right. Pass `"description"` in `params.json` (it falls back to
`parameters.Description`), and use the **same** string as the part's Excel so the two agree.
This runs **as its own task too**, not only inside new-part creation: whenever the user hands
over one or more `.SchLib` files and wants their parameters filled/updated (e.g. "\schlib", "add
@ -375,7 +402,8 @@ Leave any genuinely-unknown field blank — the SOP hides blank parameters, so a
empty until filled. The full method for the second-source search is in
`references/schlib_parameters.md`.
Collect the values into a `params.json` and write them into the symbol:
Collect the values into a `params.json` — with `"description"` alongside `"parameters"` — and
write them into the symbol:
```bash
python scripts/schlib_write.py --schlib <in>.SchLib --params params.json --out <stage>/<tag>/<sym>.SchLib

Binary file not shown.

0
assets/template/Type_ID.xlsx Executable file → Normal file
View File

0
assets/vecmocon-logo.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

350
references/description_format.md Executable file → Normal file
View File

@ -3,11 +3,10 @@
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
1. The **four formats derived from the SOP** — 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).
ID Format* (§6). Follow these **parameter orders** strictly. The **prefix**, however, is the
house `Class_TYPEID` form (see below), which supersedes the SOP's own prefix tokens.
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
@ -20,11 +19,27 @@ The Description is **not** a free-form sentence. It is a single string of `_`-jo
this shape:
```
PREFIX_param1_param2_..._Package_[AECQ-XXX]
Class_TYPEID_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.
- **Class_TYPEID** — the **mandatory opening two tokens** of every Description, always. This
replaces the old technology prefixes (`CHIP_RES`, `ELE_CAP`, `TANT_CAP`, `NMOS`, …) — those
are **retired and must not be used**. Examples: `Diode_TVS_…`, `Capacitor_TAN_…`,
`Resistor_FIX_…`, `Transistor_MOS_…`.
- **Class** — spelled exactly as the library-repo folder name, so a Description's first token
always matches the folder the part lives in. Take it from `CLASS_FOLDER` in
`scripts/common.py` (the authoritative map) — e.g. `Diode`, `Capacitor`, `Resistor`,
`Transistor`, `IC`, `Protection`, `Inductor_Magnetics`, `Relay_Contactor`, `Switch_Button`,
`Antenna_RF`, `Crystal_Oscillator`, `Battery_Cell`, `Audible_Indicator`, `Display_HMI`,
`Sensor`, `Thermal_Cooling`, `Connector`. Mixed case as written — do **not** upper-case it.
Note `Inductor_Magnetics` and friends already contain an `_`; that is expected and correct.
The one Class whose folder name contains spaces, `Power Conversion Module`, is written
`Power_Conversion_Module` in a Description.
- **TYPEID** — the Type ID from `references/taxonomy.md`, **always upper-case**, exactly as
the template sheet names it (`TVS`, `TAN`, `CER`, `FIX`, `MOS`, `SCH`, `LDO`, …). This is
the same typeid used in the part tag `MPN_make_typeid`, so the three agree.
- Get both from the taxonomy for the typeid you classified the part to in step 2 — never
invent or abbreviate either token.
- **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.
@ -36,7 +51,8 @@ PREFIX_param1_param2_..._Package_[AECQ-XXX]
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,
shorter procurement id (`RES_36kΩ_±0.1%_0402`) that keeps its **own** SOP notation and does
**not** take the `Class_TYPEID` prefix — 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)
@ -51,40 +67,44 @@ never put it in the Description column; **Comment** (SOP §4) is always the exac
---
# Layer 1 — the four SOP-defined formats (strict)
# Layer 1 — the four SOP-derived formats (parameter order is strict)
The **parameter orders** below are the SOP's and are not up for reinterpretation. The
**prefix** is the house `Class_TYPEID` form, which replaces the SOP §6 prefix tokens.
**Resistor**
```
Type_RES_Value_Wattage_Tolerance_Package_AECQ-XXX(optional)
Resistor_TYPEID_Value_Wattage_Tolerance_Package_AECQ-XXX(optional)
```
Example: `CHIP_RES_36kΩ_62.2mW_±0.1%_0402`
Example: `Resistor_FIX_36kΩ_62.2mW_±0.1%_0402` (was `CHIP_RES_36kΩ_62.2mW_±0.1%_0402`)
**Capacitor**
```
Type_CAP_Value_Voltage_Tolerance_Package_TemperatureCoefficient_AECQ-XXX(optional)
Capacitor_TYPEID_Value_Voltage_Tolerance_Package_TemperatureCoefficient_AECQ-XXX(optional)
```
Example: `CHIP_CAP_2.2uF_100v_±10%_1210_x7r`
Example: `Capacitor_CER_2.2uF_100v_±10%_1210_x7r` (was `CHIP_CAP_2.2uF_100v_±10%_1210_x7r`)
**Zener diode**
```
ZEN_VoltageZener(Vz)_Power_Package_AECQ-XXX(optional)
Diode_ZEN_VoltageZener(Vz)_Power_Package_AECQ-XXX(optional)
```
**TVS diode**
```
TVS_VoltageBreakdown(Vbr)_VoltageClamping(Vc)_Current(Ip)_Package_AECQ-XXX(optional)
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.
**House prefix note:** SOP §6 wrote the diodes as `DIO-Z` / `DIO-T` and the R/C formats with
technology prefixes (`CHIP_RES`, `CHIP_CAP`). Vecmocon has standardised on `Class_TYPEID` for
**every** component, so all four of these now open with `Resistor_` / `Capacitor_` / `Diode_`
plus the typeid. This is a deliberate house override of SOP §6's prefix; the parameter order
(Vz+Power for Zener; Vbr+Vc+Ip for TVS; etc.) remains exactly the SOP's.
---
@ -93,50 +113,50 @@ Zener; Vbr+Vc+Ip for TVS) is still exactly the SOP's; only the prefix token diff
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]`
## Resistor (RES family) — `Resistor_TYPEID_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) |
| FIX Thick-film chip| `Resistor_FIX` | SOP example; the strict format above |
| TFR Thin-film chip| `Resistor_TFR` | precision/low-tempco; may append tempco (ppm) |
| MFR Metal-film| `Resistor_MFR` | |
| CFR Carbon-film| `Resistor_CFR` | |
| MOR Metal-oxide| `Resistor_MOR` | high-power leaded |
| WWR Wirewound| `Resistor_WWR` | low-ohm/high-power |
| SHT Current-sense/shunt| `Resistor_SHT` | value in mΩ (e.g. `2mΩ`), power token is the sense power |
| ARR Array/network| `Resistor_ARR` | add element count/config, e.g. `4x`, before value |
| POT Potentiometer/trimmer| `Resistor_POT` | `Resistor_POT_Value_Taper_Power_Package` (taper `LIN`/`LOG`) |
| FSR Fusible/safety| `Resistor_FSR` | |
| NTC thermistor| `Resistor_NTC` | `Resistor_NTC_R25_Beta_Tolerance_Package` (R25 e.g. `10kΩ`, Beta e.g. `B3950`) |
| PTC thermistor| `Resistor_PTC` | `Resistor_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`
Example: `Resistor_SHT_2mΩ_1W_±1%_2512` · `Resistor_NTC_10kΩ_B3950_±1%_0402`
## Capacitor (CAP family) — `PREFIX_Value_Voltage_Tolerance_Package_[Dielectric]_[AECQ]`
## Capacitor (CAP family) — `Capacitor_TYPEID_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 |
| CER Ceramic MLCC| `Capacitor_CER` | SOP; dielectric token (`x7r`/`c0g`…) required |
| ELE Aluminium electrolytic| `Capacitor_ELE` | tolerance often omitted; case like `SMD,D6.3xL5.8mm` |
| TAN Tantalum| `Capacitor_TAN` | |
| PLY Aluminium-polymer| `Capacitor_PLY` | low-ESR; ESR may follow voltage |
| FLM Film (MKT/MKP)| `Capacitor_FLM` | |
| SFY Safety Class-X/Y| `Capacitor_SFY` | add safety class token (`X2`/`Y1`) after value |
| SUP Supercapacitor/EDLC| `Capacitor_SUP` | value in farads, e.g. `1F`; add ESR if rated |
Example: `ELE_CAP_33uF_25V_SMD,D6.3xL5.8mm` · `SUPERCAP_1F_5.5V_RADIAL`
Example: `Capacitor_ELE_33uF_25V_SMD,D6.3xL5.8mm` · `Capacitor_SUP_1F_5.5V_RADIAL`
## Inductor / Magnetics — `PREFIX_Value_Current_[DCR]_Package_[AECQ]`
## Inductor / Magnetics — `Inductor_Magnetics_TYPEID_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` |
| PWR Power inductor| `Inductor_Magnetics_PWR` | `Inductor_Magnetics_PWR_L_Isat_DCR_Package` (L e.g. `10uH`, Isat `3A`) |
| FBD Ferrite bead| `Inductor_Magnetics_FBD` | `Inductor_Magnetics_FBD_Impedance@freq_Current_Package` (e.g. `Inductor_Magnetics_FBD_600Ω@100MHz_2A_0603`) |
| CMC Common-mode choke| `Inductor_Magnetics_CMC` | `Inductor_Magnetics_CMC_Impedance@freq_Current_Package` |
| RFI RFI choke| `Inductor_Magnetics_RFI` | `Inductor_Magnetics_RFI_L_Current_Package` |
| XFM Transformer| `Inductor_Magnetics_XFM` | `Inductor_Magnetics_XFM_Ratio_Power_Package` (ratio e.g. `1:1`) |
| CTX Current transformer| `Inductor_Magnetics_CTX` | `Inductor_Magnetics_CTX_Ratio_Package` (e.g. `1000:1`) |
| CPL Coupled inductor| `Inductor_Magnetics_CPL` | `Inductor_Magnetics_CPL_L_Current_Package` |
## Diode — reverse-voltage / current ratings, then package
@ -145,182 +165,184 @@ The prefix is the **generic diode type code (the typeid itself)** — `REC`, `FR
| 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`) |
| REC Rectifier| `Diode_REC` | `Diode_REC_Vrrm_Io_Package` |
| FRD Fast-recovery| `Diode_FRD` | `Diode_FRD_Vrrm_Io_trr_Package` |
| SCH Schottky| `Diode_SCH` | `Diode_SCH_Vr_Io_Package` |
| SIC SiC Schottky| `Diode_SIC` | `Diode_SIC_Vr_Io_Package` |
| ZEN Zener| `Diode_ZEN` | `Diode_ZEN_Vz_Power_Package` |
| TVS TVS| `Diode_TVS` | `Diode_TVS_Vbr_Vc_Ip_Package` |
| ESD ESD protection| `Diode_ESD` | `Diode_ESD_Vrwm_Vc_Channels_Package` |
| SWI Switching/small-signal| `Diode_SWI` | `Diode_SWI_Vr_Io_trr_Package` |
| BRG Bridge rectifier| `Diode_BRG` | `Diode_BRG_Vrrm_Io_Package` |
| LED Indicator LED| `Diode_LED` | `Diode_LED_Color_Vf_If_Package` (color e.g. `RED`) |
Example (Schottky BAT46WJ, 100 V / 250 mA): `SCH_100V_0.25A_SOD-323F`
Example (Schottky BAT46WJ, 100 V / 250 mA): `Diode_SCH_100V_0.25A_SOD-323F`
## Transistor — `PREFIX_Voltage_Current_[Rds(on)]_Package_[AECQ]`
## Transistor — `Transistor_TYPEID_[Polarity]_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.
Since the prefix is now `Transistor_TYPEID`, the polarity/channel can no longer ride in the
prefix (the old `NMOS`/`PMOS`/`BJT_NPN` tokens are retired). It is carried as **its own token
immediately after the prefix**: `N`/`P` for FETs, `NPN`/`PNP` for BJTs and digital transistors.
Types with no polarity variant (GaN, IGBT) omit the token entirely.
| 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` |
| BJT BJT | `Transistor_BJT` | `Transistor_BJT_Polarity_Vceo_Ic_Package` (polarity `NPN`/`PNP`) |
| MOS MOSFET (Si) | `Transistor_MOS` | `Transistor_MOS_Channel_Vds_Id_Rdson_Package` (channel `N`/`P`) |
| SCM SiC MOSFET | `Transistor_SCM` | `Transistor_SCM_Channel_Vds_Id_Rdson_Package` |
| GAN GaN FET | `Transistor_GAN` | `Transistor_GAN_Vds_Id_Rdson_Package` |
| IGBT IGBT | `Transistor_IGBT` | `Transistor_IGBT_Vces_Ic_Package` |
| JFET JFET | `Transistor_JFET` | `Transistor_JFET_Channel_Vds_Idss_Package` |
| DIG Digital/bias-R transistor | `Transistor_DIG` | `Transistor_DIG_Polarity_Vceo_R1/R2_Package` |
Example: `NMOS_20V_6A_15mΩ_SOT-23` · `BJT_NPN_50V_0.1A_SOT-416FL`
Example: `Transistor_MOS_N_20V_6A_15mΩ_SOT-23` · `Transistor_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` |
| MCU Microcontroller| `IC_MCU` | `IC_MCU_Core_Flash_Package` (e.g. `IC_MCU_M0+_128Kb_LQFP-48`) |
| LDO LDO regulator| `IC_LDO` | `IC_LDO_Vout_Iout_Package` (`ADJ` if adjustable) |
| DCD DC-DC IC| `IC_DCD` | `IC_DCD_Topology_Vin_Iout_Package` (topology `BUCK`/`BOOST`/`BUCKBOOST`) |
| PMU PMIC| `IC_PMU` | `IC_PMU_Rails_Package` |
| BMS BMS AFE| `IC_BMS` | `IC_BMS_Cells_Package` (e.g. `16S`) |
| DRV Gate/motor driver| `IC_DRV` | `IC_DRV_Type_Voltage_Current_Package` (type `GATE`/`MOTOR`/`HB`) |
| AMP Amplifier/op-amp| `IC_AMP` | `IC_AMP_GBW_Channels_Package` |
| CMP Comparator| `IC_CMP` | `IC_CMP_Channels_Package` |
| VRF Voltage reference| `IC_VRF` | `IC_VRF_Voltage_Tolerance_Package` |
| ADC ADC| `IC_ADC` | `IC_ADC_Bits_Rate_Package` |
| DAC DAC| `IC_DAC` | `IC_DAC_Bits_Channels_Package` |
| ISO Isolator/optocoupler| `IC_ISO` | `IC_ISO_Channels_IsolationV_Package` |
| XCV Transceiver| `IC_XCV` | `IC_XCV_Bus_Speed_Package` (bus `CAN`/`RS485`; e.g. `IC_XCV_CAN_5Mbps_SOIC-8`) |
| AFE Analog front end| `IC_AFE` | `IC_AFE_Function_Package` |
| MEM Memory| `IC_MEM` | `IC_MEM_Type_Size_Interface_Package` (e.g. `IC_MEM_FLASH_128Mb_SPI_SOIC-8`) |
| LOG Logic gate| `IC_LOG` | `IC_LOG_Function_Package` (e.g. `AND2`, `BUF`) |
| SEN Sensor IC| `IC_SEN` | `IC_SEN_Type_Package` |
| IFC Interface/expander| `IC_IFC` | `IC_IFC_Function_Package` |
| CLK Clock/RTC| `IC_CLK` | `IC_CLK_Freq_Package` (or `RTC_Package`) |
| SVR Supervisor/reset| `IC_SVR` | `IC_SVR_Threshold_Package` |
| MTR Energy metering| `IC_MTR` | `IC_MTR_Phases_Package` |
## Protection Device — `PREFIX_ratings_Package`
## Protection Device — `Protection_TYPEID_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` |
| FUS Fuse| `Protection_FUS` | `Protection_FUS_Current_Voltage_Package` (speed `F`/`T` may precede current) |
| RSF Resettable/PPTC| `Protection_RSF` | `Protection_RSF_Ihold_Voltage_Package` |
| VAR Varistor/MOV| `Protection_VAR` | `Protection_VAR_Vrms_Energy_Package` |
| GDT Gas-discharge tube| `Protection_GDT` | `Protection_GDT_Vspark_Package` |
| CBK Circuit breaker| `Protection_CBK` | `Protection_CBK_Current_Poles_Package` |
## Power Conversion Module — `PREFIX_Vin_Vout_Power_Package`
## Power Conversion Module — `Power_Conversion_Module_TYPEID_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` |
| DCM DC-DC module| `Power_Conversion_Module_DCM` | non-isolated PoL |
| IDC Isolated DC-DC| `Power_Conversion_Module_IDC` | isolated brick |
| INV Inverter (DC-AC)| `Power_Conversion_Module_INV` | `Power_Conversion_Module_INV_Power_Voltage_Package` |
| OBC On-board charger| `Power_Conversion_Module_OBC` | `Power_Conversion_Module_OBC_Power_Voltage_Package` |
| CHG Charger module| `Power_Conversion_Module_CHG` | `Power_Conversion_Module_CHG_Power_Voltage_Package` |
| PSU AC-DC SMPS| `Power_Conversion_Module_PSU` | `Power_Conversion_Module_PSU_Power_Vout_Package` |
| RCM Rectifier module| `Power_Conversion_Module_RCM` | `Power_Conversion_Module_RCM_Current_Voltage_Package` |
## Relay / Contactor — `PREFIX_CoilVoltage_ContactRating_Package`
## Relay / Contactor — `Relay_Contactor_TYPEID_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 |
| RLS Signal relay| `Relay_Contactor_RLS` | contact rating e.g. `2A/30V` |
| RLP Power relay| `Relay_Contactor_RLP` | |
| SSR Solid-state relay| `Relay_Contactor_SSR` | `Relay_Contactor_SSR_ControlV_LoadRating_Package` |
| RLR Reed relay| `Relay_Contactor_RLR` | |
| CTC Contactor| `Relay_Contactor_CTC` | HV/HC contact rating |
## Switch / Button — `PREFIX_[Positions]_Rating_Package`
## Switch / Button — `Switch_Button_TYPEID_[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` |
| SWT Tactile| `Switch_Button_SWT` | rating e.g. `50mA/12V` |
| PBT Push button| `Switch_Button_PBT` | |
| DSW DIP/slide| `Switch_Button_DSW` | positions e.g. `4P` |
| RSW Rocker/toggle| `Switch_Button_RSW` | |
| RSY Rotary| `Switch_Button_RSY` | positions e.g. `12POS` |
## Connector — `CON_TYPE_Positions_Pitch_Package`
## Connector — `Connector_TYPEID_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` | |
| CWB Wire-to-board| `Connector_CWB` | e.g. `Connector_CWB_2x2_P2.0` |
| CBB Board-to-board| `Connector_CBB` | |
| HDR Header/socket| `Connector_HDR` | pitch e.g. `2.54mm` |
| FFC FFC/FPC| `Connector_FFC` | |
| USB USB/data| `Connector_USB` | add USB type (`C`, `MICRO`) |
| PWC Power/high-current| `Connector_PWC` | add current rating |
| TBK Terminal block| `Connector_TBK` | |
## Antenna / RF — `PREFIX_Band_Package`
## Antenna / RF — `Antenna_RF_TYPEID_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` |
| ANC Chip antenna| `Antenna_RF_ANC` | band e.g. `2.4GHz` |
| ANP PCB/trace antenna| `Antenna_RF_ANP` | |
| ANE External/whip| `Antenna_RF_ANE` | add connector token |
| SAW SAW filter| `Antenna_RF_SAW` | `Antenna_RF_SAW_Freq_Package` |
| RFM RF/wireless module| `Antenna_RF_RFM` | protocol e.g. `BLE`, `WIFI`, `LTE` |
## Crystal / Oscillator / Timing — `PREFIX_Freq_[Load]_Package`
## Crystal / Oscillator / Timing — `Crystal_Oscillator_TYPEID_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` |
| XTL Crystal| `Crystal_Oscillator_XTL` | `Crystal_Oscillator_XTL_Freq_LoadCap_Package` (e.g. `Crystal_Oscillator_XTL_48MHz_18pF_SMD2016-4P`) |
| OSC Crystal oscillator| `Crystal_Oscillator_OSC` | `Crystal_Oscillator_OSC_Freq_Package` |
| MMO MEMS oscillator| `Crystal_Oscillator_MMO` | |
| RSN Ceramic resonator| `Crystal_Oscillator_RSN` | `Crystal_Oscillator_RSN_Freq_Package` |
## Battery / Cell — `PREFIX_Capacity_Voltage_Format`
## Battery / Cell — `Battery_Cell_TYPEID_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` |
| CLI Li-ion cell| `Battery_Cell_CLI` | format e.g. `18650`; capacity `2600mAh` |
| CLF LiFePO4 cell| `Battery_Cell_CLF` | |
| CCO Coin/button| `Battery_Cell_CCO` | add chemistry (`CR`/`LIR`) + size (`2032`) |
| CNI NiMH| `Battery_Cell_CNI` | |
| BPK Battery pack| `Battery_Cell_BPK` | `Battery_Cell_BPK_Voltage_Capacity` (e.g. `48V_20Ah`) |
| CHL Cell holder| `Battery_Cell_CHL` | `Battery_Cell_CHL_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` |
| BUZ Magnetic buzzer| `Audible_Indicator_BUZ` | `Audible_Indicator_BUZ_Voltage_Freq_Package` |
| PBZ Piezo buzzer| `Audible_Indicator_PBZ` | `Audible_Indicator_PBZ_Voltage_Freq_Package` |
| SPK Speaker| `Audible_Indicator_SPK` | `Audible_Indicator_SPK_Power_Impedance_Package` |
| IND Indicator lamp| `Audible_Indicator_IND` | `Audible_Indicator_IND_Color_Voltage_Package` |
## Display / HMI — `PREFIX_Resolution/Digits_Size_Interface`
## Display / HMI — `Display_HMI_TYPEID_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`) |
| DSG 7-segment| `Display_HMI_DSG` | `Display_HMI_DSG_Digits_Color_Package` |
| OLE OLED| `Display_HMI_OLE` | resolution e.g. `128x64`, size `0.96in` |
| LCD LCD| `Display_HMI_LCD` | char (`16x2`) or graphic resolution |
| TFT TFT| `Display_HMI_TFT` | resolution + size + interface (`SPI`/`RGB`) |
## Sensor (discrete / module) — `SEN_TYPE_Range_[Interface]_Package`
## Sensor (discrete / module) — `Sensor_TYPEID_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 |
| STE Temperature| `Sensor_STE` | range + interface (`I2C`/`ANALOG`) |
| SCU Current (Hall)| `Sensor_SCU` | range e.g. `±50A` |
| SVO Voltage/isolated| `Sensor_SVO` | |
| SHA Hall/position| `Sensor_SHA` | type (`LATCH`/`LINEAR`) |
| SIM IMU/accel| `Sensor_SIM` | axes (`6AXIS`) + interface |
| SPR Pressure| `Sensor_SPR` | 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` |
| FAN Fan| `Thermal_Cooling_FAN` | `Thermal_Cooling_FAN_Size_Voltage_Airflow` (size e.g. `40x40mm`) |
| HSK Heatsink| `Thermal_Cooling_HSK` | `Thermal_Cooling_HSK_Dimensions_ThermalResistance` |
| TPD Thermal pad/TIM| `Thermal_Cooling_TPD` | `Thermal_Cooling_TPD_Conductivity_Thickness` |
---

32
references/schlib_parameters.md Executable file → Normal file
View File

@ -22,20 +22,16 @@ inside Altium; keep it as a fallback if a particular file doesn't round-trip.)
Use these exact Altium parameter names (they must match the symbol, per the SOP screenshot).
The **Comment** field is set to the MPN (SOP §4), and the **Description** field is the strict
string from `references/description_format.md` — which **overwrites** whatever prose Ultra
Librarian put in `Description` (UL's text is often wrong: a real 6N137 export read
`SMD-8 CPLR SNGL 10MBD 100V/us -e3` when the datasheet CMR is 1000 V/µs).
string from `references/description_format.md`.
Beyond this SOP set, also stamp on **every engineering parameter from the part's typeid sheet**
(for an `ISO`: Isolator Type, Isolation Voltage, No. of Channels, Data Rate, Supply Voltage,
Creepage, Package, Power, Max Output Current). Skip the housekeeping columns (`MPN_make_type`,
Skill/Template Version) and the four Library/Footprint Ref/Path columns — Altium already holds
those as the symbol's model links, so repeating them as parameters makes two sources of truth.
**Encoding gotcha:** Altium parameter records are **latin-1**, so a value containing `≥`, `≤`,
`±`-beyond-latin1, `µ` (U+00B5 is fine, U+03BC is not) or similar will crash `schlib_write.py`
with a `UnicodeEncodeError`. Rephrase into latin-1 (`≥ 7 mm` → `7 mm min.`) rather than dropping
the value; `°` (U+00B0) is latin-1 and safe. The workbook keeps the original notation.
**The Description is not a parameter record.** It is the `ComponentDescription` field of the
component's `RECORD=1` header — the box shown at *Properties → General → Description*, above the
Parameters table. Ultra-Librarian ships it as the literal placeholder text `Description`, so a
symbol whose parameters are all correctly filled will *still* show the word "Description" in
Altium unless that header field is rewritten. `schlib_write.py` now sets it in the same pass as
the parameters: pass `"description"` in `params.json`, or let it fall back to your
`parameters.Description`. Always give it the same strict `Class_TYPEID` string you wrote into the
part's Excel, so the symbol and the workbook agree.
| Parameter | Source | Notes |
|-----------|--------|-------|
@ -57,9 +53,7 @@ handed to you.** Open the PDF, find each real value (`Value`, `Manufacturer Part
`Manufacturer`, `Operating Temperature`, `Tolerance`, `Datasheet`, `ROHS`, and `Process` by
inference from the package), and fill them verified. An honest blank beats a guess — the SOP
hides blank parameters, so a gap just stays empty until someone fills it. Only **one** field is
purely internal and is never on a datasheet: `Vecmocon Part Code`. Use it if the engineer already
supplied it; otherwise **leave it blank and note the gap in your summary — don't stop to ask**.
Stamping the symbol is automatic and non-interactive (SKILL.md, step 6), so no field blocks it.
purely internal and must come from the engineer: `Vecmocon Part Code` — ask for it.
The second-source pair (`Manufacturer 2` / `Manufacturer Part 2`) is **left blank for now**
don't populate it by default. It simply stays hidden in Altium until someone fills it later.
@ -95,6 +89,7 @@ symbol's Library Ref (from `altium_refs.py`); omit it to apply to every componen
{
"component": "CC0402FRNPO9BN120",
"comment": "CC0402FRNPO9BN120",
"description": "Capacitor_CER_12pF_50V_±1%_0402_NPO",
"parameters": {
"Component Type": "Capacitor",
"Value": "12pF_0402",
@ -122,10 +117,7 @@ python scripts/schlib_write.py --schlib <in>.SchLib --params params.json --out <
`params.json` may carry a `"remove"` list (defaults to `["Manufacturer_Name",
"Manufacturer_Part_Number", "Copyright", "Component_Type"]`); those Ultra-Librarian defaults are
stripped and the SOP params — including the spaced `Component Type` = Class — added. Real UL
exports also ship **placeholder** params whose Text is just the name back again (`Type` = `Type`,
`RefDes` = `RefDes`, sometimes `TYPE`); add those to `remove` too — they're noise, not data. After
writing, grep the output for `Ultra Librarian` / `Manufacturer_Name` and confirm the count is 0. The script targets the component named in `"component"` (its Library Ref / storage name),
stripped and the SOP params — including the spaced `Component Type` = Class — added. The script targets the component named in `"component"` (its Library Ref / storage name),
or every component if omitted, and self-checks the output re-opens as a valid OLE. Deliver the
resulting `.SchLib`, and have the engineer open it in Altium once to confirm it loads, then Save
to Server with a revision note per the SOP.

0
references/taxonomy.md Executable file → Normal file
View File

1
scripts/.__wtest Normal file
View File

@ -0,0 +1 @@
test

0
scripts/altium_params.py Executable file → Normal file
View File

0
scripts/altium_refs.py Executable file → Normal file
View File

0
scripts/append_parameter.py Executable file → Normal file
View File

0
scripts/common.py Executable file → Normal file
View File

0
scripts/fill_templates.py Executable file → Normal file
View File

0
scripts/gitea_components.py Executable file → Normal file
View File

0
scripts/push_to_gitea.sh Executable file → Normal file
View File

59
scripts/schlib_write.py Executable file → Normal file
View File

@ -16,6 +16,9 @@ What it does to the target component's Data stream:
and the UL ``Component_Type`` (Vecmocon adds its own spaced ``Component Type`` = Class instead);
override this default set with a "remove" list in params.json,
- adds/updates the SOP parameters from params.json (see references/schlib_parameters.md),
- sets the component's ComponentDescription (the Description shown in Altium's Properties
panel) this lives in the RECORD=1 header, NOT in a parameter record, and Ultra-Librarian
ships it as the literal placeholder "Description", so it must be rewritten explicitly,
- leaves pins, graphics, the Comment and all other records exactly as they were.
Usage:
@ -23,9 +26,13 @@ Usage:
params.json (same shape altium_params.py uses):
{"component":"JMK105BJ105KV-F", # LibRef / component-storage name; omit -> all comps
"description":"Capacitor_CER_1uF_35V_±10%_0402_x7r", # optional; else parameters.Description
"parameters":{"Value":"1u","Manufacturer":"Taiyo Yuden","Component Type":"Capacitor", ...},
"remove":["Manufacturer_Name","Manufacturer_Part_Number","Copyright","Component_Type"]} # optional; default
The Description is the same strict Class_TYPEID string written to the part's Excel
(references/description_format.md), so symbol and workbook always agree.
IMPORTANT: this writes Altium's own binary format from outside Altium. It is validated to
re-open as a well-formed OLE with every other stream byte-identical, but ALWAYS open the result
in Altium once to confirm it loads before relying on it.
@ -122,9 +129,40 @@ def _rec_name(block):
return t.split('|Name=')[1].split('|')[0] if '|Name=' in t else None
def edit_data(data, params, remove):
def _text_block(text):
"""Re-wrap an edited text record as its 4-byte length prefix + NUL-terminated payload."""
payload=text.encode('latin-1')+b'\x00'
return struct.pack('<I', len(payload))+payload
def _set_description(blk, description):
"""Set ComponentDescription on a RECORD=1 component-header block.
The symbol's Description (Altium: Properties -> General -> Description) is NOT a parameter
record it's the ComponentDescription field of the RECORD=1 header. Ultra-Librarian ships
the literal placeholder `ComponentDescription=Description`, so unless this is rewritten the
symbol shows the word "Description" in Altium even after every SOP parameter is filled.
"""
text=blk[4:-1].decode('latin-1')
if not text.startswith('|RECORD=1|'):
return blk
if 'ComponentDescription=' in text:
parts=text.split('|')
for i,tok in enumerate(parts):
if tok.startswith('ComponentDescription='):
parts[i]='ComponentDescription='+description
text='|'.join(parts)
elif '|PartCount=' in text: # field absent entirely -> insert it
text=text.replace('|PartCount=', f'|ComponentDescription={description}|PartCount=', 1)
else:
text=text+f'|ComponentDescription={description}'
return _text_block(text)
def edit_data(data, params, remove, description=None):
"""Return a new Data stream: drop `remove` params, drop any SOP-name params (re-added
fresh), keep everything else, then append the SOP params. Pins/graphics/tail untouched."""
fresh), keep everything else, then append the SOP params. When `description` is given, the
RECORD=1 ComponentDescription field is rewritten too. Pins/graphics/tail untouched."""
leading, tail = _leading_text_records(data)
sop_names=set(params)
kept=[]
@ -132,6 +170,8 @@ def edit_data(data, params, remove):
nm=_rec_name(blk)
if nm is not None and (nm in remove or nm in sop_names):
continue # drop UL duplicates + stale SOP copies
if description is not None and nm is None:
blk=_set_description(blk, description) # RECORD=1 header carries the Description
kept.append(blk)
added=[_param_record(20+i, nm, val) for i,(nm,val) in enumerate(params.items())]
return b''.join(kept)+b''.join(added)+tail
@ -219,6 +259,9 @@ def write_params(schlib, params_json, out):
component=params_json.get("component") or None
fields=params_json.get("parameters", {}) or {}
remove=params_json.get("remove", DEFAULT_REMOVE)
# The symbol's Description: taken from "description", else the "Description" parameter if the
# caller put it there (it's the same strict Class_TYPEID string that goes in the part's Excel).
description=params_json.get("description") or fields.get("Description") or None
entries, paths, content = read_container(schlib)
# target Data stream sid(s): a stream named 'Data' whose parent storage == component (or all)
@ -230,7 +273,7 @@ def write_params(schlib, params_json, out):
if not targets:
sys.exit(f"no component Data stream found" + (f" for '{component}'" if component else ""))
for sid in targets:
content[sid]=edit_data(content[sid], fields, remove)
content[sid]=edit_data(content[sid], fields, remove, description)
blob=rebuild(entries, content)
open(out,'wb').write(blob)
@ -239,17 +282,21 @@ def write_params(schlib, params_json, out):
if not olefile.isOleFile(out):
sys.exit("ERROR: rebuilt file is not a valid OLE — aborting")
ole=olefile.OleFileIO(out)
ok=True
ok=True; desc_ok=(description is None)
for e in ole.listdir(streams=True):
if e[-1].lower()=="data":
t=ole.openstream(e).read().decode('latin-1','ignore')
for nm in fields:
if f"|Name={nm}|" not in t and f"|Name={nm}\x00" not in t and f"Name={nm}" not in t:
ok=False
if description is not None and f"ComponentDescription={description}|" in t:
desc_ok=True
ole.close()
n_comp=len(targets)
print(f"wrote {out} ({len(fields)} params into {n_comp} component(s); removed {remove}) "
f"{'[self-check OK]' if ok else '[WARN: verify params]'}")
desc_note=f"; description set" if description else "; no description given"
flag='[self-check OK]' if (ok and desc_ok) else '[WARN: verify params/description]'
print(f"wrote {out} ({len(fields)} params into {n_comp} component(s); removed {remove}"
f"{desc_note}) {flag}")
def main():