diff --git a/SKILL.md b/SKILL.md old mode 100755 new mode 100644 index f76b0a5..e96c62d --- a/SKILL.md +++ b/SKILL.md @@ -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 // --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 //.SchLib \ + --params params.json \ + --out //.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 `/` should now hold the four files: the per-part `.xlsx`, the -datasheet (name it `_data.`), 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 `_data.`), 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 .SchLib --params params.json --out //.SchLib diff --git a/assets/CHANGELOG.xlsx b/assets/CHANGELOG.xlsx index 16a0459..9a87278 100644 Binary files a/assets/CHANGELOG.xlsx and b/assets/CHANGELOG.xlsx differ diff --git a/assets/template/Type_ID.xlsx b/assets/template/Type_ID.xlsx old mode 100755 new mode 100644 diff --git a/assets/vecmocon-logo.png b/assets/vecmocon-logo.png old mode 100755 new mode 100644 diff --git a/references/description_format.md b/references/description_format.md old mode 100755 new mode 100644 index 9150fdb..ad74b12 --- a/references/description_format.md +++ b/references/description_format.md @@ -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` | --- diff --git a/references/schlib_parameters.md b/references/schlib_parameters.md old mode 100755 new mode 100644 index d6a1b5e..d94d291 --- a/references/schlib_parameters.md +++ b/references/schlib_parameters.md @@ -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 .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. diff --git a/references/taxonomy.md b/references/taxonomy.md old mode 100755 new mode 100644 diff --git a/scripts/.__wtest b/scripts/.__wtest new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/scripts/.__wtest @@ -0,0 +1 @@ +test diff --git a/scripts/altium_params.py b/scripts/altium_params.py old mode 100755 new mode 100644 diff --git a/scripts/altium_refs.py b/scripts/altium_refs.py old mode 100755 new mode 100644 diff --git a/scripts/append_parameter.py b/scripts/append_parameter.py old mode 100755 new mode 100644 diff --git a/scripts/common.py b/scripts/common.py old mode 100755 new mode 100644 diff --git a/scripts/fill_templates.py b/scripts/fill_templates.py old mode 100755 new mode 100644 diff --git a/scripts/gitea_components.py b/scripts/gitea_components.py old mode 100755 new mode 100644 diff --git a/scripts/push_to_gitea.sh b/scripts/push_to_gitea.sh old mode 100755 new mode 100644 diff --git a/scripts/schlib_write.py b/scripts/schlib_write.py old mode 100755 new mode 100644 index cc4288a..1c58728 --- a/scripts/schlib_write.py +++ b/scripts/schlib_write.py @@ -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(' 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():