OV-TOOLS-HWRELEASE · v0.4 · 2026-09-10Download PDF
| Doctype | Design Document |
|---|---|
| Doc id | OV-TOOLS-HWRELEASE |
| Product line | openvvvf |
| Applies to | openvvvf-control-module, chassis-size-2 |
| Version | 0.4 |
| Date | 2026-09-10 |
| Description | How hardware releases flow from InverterGen5 git tags into the PCB Tool, BOM Tool, and Data/Releases, and the conventions that drive them. |
| Nav order | 604 |
| Normative refs | OV-TOOLS-INDEX |
HWRelease System Architecture
This document describes how hardware release data flows from the hardware repository into the documentation site, and the conventions that make it work. Read this before changing Tools/HWRelease, the release data, or the hardware-side spec files.
Repositories and data flow
InverterGen5 (hardware repo) Documentation (this repo)
--------------------------- -------------------------
KiCad projects ──┐
Mechanical/Fab ──┤ git tag (release) Tools/HWRelease
fab_spec.yaml ───┼──────────────► hwrelease update
fab_defaults.yaml┘ │
├─ kicad-cli exports (per board):
│ schematic PDF, BOM CSV, gerber zip,
│ DRC, STEP, iBOM HTML, renders
├─ BOMManager generate (per chassis):
│ vendor BOMs, variants, pricing
├─ mech-part export (Mechanical/Fab)
▼
Data/Releases/<chassis>/<rev>/...
Data/Releases/manifest.json
│
hwrelease build-viewer (automatic)
▼
Docs/Tools/PCB-Tool/pcb-tool.html (per-board pages)
Docs/Tools/BOM-Tool/bom-tool.html (per-chassis ordering)
│
docgen site (copies Data/Releases into site/)
The release workflow
- In InverterGen5: make changes (bump
(rev "X")in a board's.kicad_sch/.kicad_pcb, edit specs; for mech-only changes, rename the FreeCAD part labels andMechanical/Fab/<part>folders to the new rev suffix), commit, push, and create a GitHub release (which creates a tag, e.g.C2-A). A tag named<chassis-short>-<rev>(e.g.C2-B) pins that chassis' release rev and scopes the export to that chassis, so a mechanical-only change set can move the chassis revision without any board rev bump. - Here: run
make hw-update(=hwrelease update). It fetches tags, and for each tag not yet in the manifest: - Exports the tag's
Hardware/tree viagit archiveinto a temp dir (the hardware repo's working tree is never touched). - Reads each board's revision from
(rev "X")in its KiCad files. - Exports board BOM CSVs (
<Board>.csvbeside each project, boards and wiring harnesses): BOMManager discovers BOMs from these files, so this step must happen before generation. - Regenerates the chassis vendor BOMs with this repo's BOMManager (
generate --variants), so BOMs and prices are always built from the tag's sources, never copied stale. BOMManager also writes aSubassembly_Pricing.jsonnext to everyConsolidated_BOM.csv(base build, spares tiers, build variants); the export copies each one next to its CSV in the release tree, records them undersubassembly_pricing, and reads the manifest's per-variant price totals from them. - Extracts fabricated parts from the FreeCAD model (
Mechanical/*.FCStd): per part (Body/Group labeled with the exact part number;...001instance suffixes deduplicated) a fresh STEP, STL, Blender renders, and aholes.jsondiameter histogram, followed by a spec-vs-model hole check. It also harvests McMaster hardware (labels like91292A134_...Screw001are counted per part number, merged intoMechanicalBOM.txt; model count wins for modeled parts, unmodeled lines like consumables are kept, model-only parts are appended, then cross-checked with warnings) and counts instances per fabricated part (model_parts.json), cross-checked against each part'sinfo.txtquantity. A chassis with no boards (mechanical concept only, e.g. Chassis3) is exported too whenever it has aMechanical/*.FCStdorMechanical/Fab/; itsCHASSIS-<short>-<rev>entry falls back to the tag name as rev. A chassis with no vendor BOMs and no mech parts is skipped. - Exports per-board artifacts (named
<part-number>-<kind>.<ext>) and mechanical parts. - Updates
Data/Releases/manifest.jsonand regenerates both tool pages. - Commit
Data/Releases/and the generated pages.
Already-exported revisions are skipped; hwrelease update --tag <T> --force regenerates (e.g. after moving a tag).
Manifest (Data/Releases/manifest.json)
Single source of truth for the tools. Three entry kinds:
- Boards: key
HW-<chassis>-PCB-<desc>-<rev>(e.g.HW-C2-PCB-CTRL-A): artifacts map (ibom,schematic_pdf,bom_csv,gerber_zip,drc,step,renders,fab_spec), plussource_tag/source_url. - Chassis releases: key
CHASSIS-<chassis>-<rev>:vendor_boms(CSV paths per vendor),variants(spares tiers),price_estimate(vendor subtotals, grand total, per-variant totals and per-variant vendor subtotals),subassembly_pricing(Subassembly_Pricing.jsonpaths per output:baseplustiersandbuildsmaps when those exist),pricing_report. Chassis with avariants.yamlalso record the build-variant artifacts:build_variants(names),variant_comparison(Variant_Comparison.md), andvariants_manifest(variants.json). Entries exist whenever the chassis has vendor BOMs or mech parts, so mechanical-only chassis (no boards) appear too; their artifacts may be empty, with the parts carried by the mech entries. - Mechanical parts: key = part number (e.g.
HW-C2-DCLBB-A), withmech: true:step,image,info/info_fields(from SendCutSend cart imports),fab_spec. A part exported by several releases is keyed per release (bare<pn>while unique, else<pn>--<chassis>-<rev>, e.g.HW-C2-CHSP-B--C2-C), since each release dir has its own on-disk copy;hwrelease migrate-mechrebuilds these entries from the exported trees without the hardware repo.
Conventions (hardware repo)
These files in InverterGen5 drive the tools; keep them current:
Boards/fab_defaults.yaml: chassis-wide ordering notes merged into every board (e.g. serial-number barcode rule).Boards/<Board>/fab_spec.yaml: per-board fab options and notes:
```yaml
options: # JLCPCB quote-form settings
outer_copper: 2 oz
notes:- "2 oz outer copper required (high-current DC bus)."
```
- "2 oz outer copper required (high-current DC bus)."
Mechanical/Fab/<part>/fab_spec.yaml: per-part ordering spec:
```yaml
process: laser_cut # or 3d_print
material: "Copper C110"
thickness_mm: 4.75
services:
bending: true
tapping:- thread: "M6x1.0"
holes: "all ⌀5.0 mm through-holes (4x)" # reference holes by drill diameter
countersink: - for: "M5 flathead"
holes: "⌀5.5 mm holes on top face (2x)"
notes: - "Deburr both sides"
`` For3d_print, usematerial`/print notes instead (layer height, infill, orientation). Holes are referenced by drill diameter so a future FreeCAD extractor can verify specs against the model.
- thread: "M6x1.0"
Mechanical/Fab/<part>/info.txt: auto-imported SendCutSend cart record (price, dims); do not hand-edit.
Conventions (this repo)
- Ordering walkthroughs live next to
Docs/Tools/BOM-Tool/Index.mdasordering-<vendor>-<n>.png+ optionalordering-<vendor>-<n>.txtcaption (vendors:mouser,digikey,mcmaster,sendcutsend,jlc). Steps stop at the first missingn. The PCBs vendor uses thejlcfiles. Data/Releases/is committed generated data: never hand-edit; regenerate with--force.- Tool pages are generated (
hwrelease build-viewer); editTools/HWRelease/hwrelease/viewer.py, not the HTML.
The tools
- PCB Tool (
/Tools/PCB-Tool/pcb-tool.html): every released board by part number; renders, embedded interactive assembly (iBOM), part-number-named artifacts, "Open Source" link to the tag, and the board'sfab_specas an Ordering specifications table. - BOM Tool (
/Tools/BOM-Tool/bom-tool.html): chassis / revision / spares-variant selectors, a per-subassembly price selector (order just one board/harness group, pack rounding applied per subassembly), vendor list with price subtotals and a total estimate, CSV preview, per-vendor order links, ordering walkthroughs, gerber downloads + per-board notes on the PCBs view, and per-part spec cards on the SendCutSend view.
Build variants (implemented)
Voltage-class builds (e.g. 200V / 450V) that swap both electrical parts (Mouser lines) and mechanical parts (heatspreader, printed holders) are implemented: each chassis declares its builds in Hardware/<Chassis>/variants.yaml in the hardware repo (exclude/add/setqty rules), and BOMManager's generate applies them (--variant <name> builds a subset; HWRelease runs generate, so every declared variant is built). The default variant's outputs land at the FabricationData/ root; the others go under FabricationData/Builds/<variant>/, with Variant_Comparison.md and variants.json at the root. HWRelease copies these into the release directory and records them in the manifest (build_variants, variant_comparison, variants_manifest).
Planned (roadmap)
- BOM Tool build dropdown: the BOM Tool has chassis / revision / spares-variant selectors, but no build-configuration selector for the
variants.yamlbuilds yet. - FreeCAD spec auto-fill: extend the implemented model extraction to fill
fab_spec.yamlfields from model properties. - Mechanical parts explorer: a dedicated tool page for mech parts (the manifest entries and spec cards are the seed).
Maintenance cheatsheet
| Task | Where |
|---|---|
| New board revision | bump (rev ...) in KiCad files, tag release, make hw-update |
| New mech-only chassis revision | rename the FreeCAD part labels (and Mechanical/Fab/<part> folders) to the new rev suffix, tag <short>-<rev> (e.g. C2-B), make hw-update. A chassis-named tag pins the chassis rev and scopes the export to that chassis, so no board rev bump is needed |
| Board ordering spec (2 oz copper, finish) | Boards/<Board>/fab_spec.yaml in InverterGen5 |
| Chassis-wide fab note | Boards/fab_defaults.yaml |
| Mech part spec (tap/countersink/bend/print) | Mechanical/Fab/<part>/fab_spec.yaml |
| Vendor ordering walkthrough | Docs/Tools/BOM-Tool/ordering-<vendor>-<n>.{png,txt} |
| Part prices | BOMManager (Data/Parts/PriceCache.json / vendor APIs): regenerate via hwrelease update |
