Interop and costing
Reference. Generated from docs/interop.md.
Three ways records and designs move in and out of WireHub, and what a BOM costs.
None of it is shop-specific: the formats are public, and the two importers are bundled
modules (docs/modules.md, "Interop modules").
WireViz YAML (modules/wireviz)#
Import. The Library's Import… takes a WireViz harness (.yml, .yaml). It runs as an
import job, so there is a review step and Publish commits one change set; nothing is written
before that. The proposal is a design plus any new connector and wire-stock records it needs.
| WireViz | WireHub |
|---|---|
connectors | connector instances. A library connector is chosen only when pn, mpn or type (also type subtype) equals a record's part number, id, alias or label and the pin count agrees; otherwise a connector record is proposed from type, subtype (male/female become the gender), pincount, pins and pinlabels, with an INFERRED src |
cables | wire segments. Stock chosen the same way (pn, mpn, type); otherwise a stock is proposed from wirecount or colors, color_code, gauge and shield |
colors, color_code | conductor colours (WHBU becomes white-blue); IEC, DIN, TEL, TELALT, T568A, T568B and BW codes are read in WireViz's published sequences (a code shorter than the wire count leaves the rest uncoloured, with a note); others are reported |
gauge | conductor area in mm2; AWG is converted with the standard diameter formula and noted |
length | segment length (metres by default; mm cm m in ft yd units read) |
wirelabels | the segment's core labels |
connections | joints. Pin and wire lists, ranges (1-4, 9-7), pin labels, s for the shield, -- arrows between connectors, connector loops |
notes | connector notes; cable and metadata notes become design notes |
metadata.title | the design's name and id |
An existing library stock's wires are numbered in its conductor order (non-bare conductors, then s
is the first shield, else the first bare conductor).
What is lossy is listed as Not carried over: … notes in the review: pin colours, appearance
attributes (image, bgcolor, style, color …), connector mating arrows, arrow direction,
additional_bom_items, category: bundle, a shield's colour, a shield's construction (a proposed shield
is a foil, flagged INFERRED), colour codes this does not read, options, tweak,
templates. A reference to a pin or wire that does not exist, a wire count that does not match, or a
design problem the library's rules find is reported, and that joint is skipped, never guessed.
Export. WireViz (YAML) in the Documents toolbar (also
GET /api/modules/wireviz/_export/wireviz-yaml?design=<id>) writes the connectors, cables and
connections WireViz can express. Anything it cannot (components, boards, breakouts, sub-assemblies, shells and
hardware, pigtails that do not twist the shield, joints that do not run from a connector pin to a cable wire, a second shield) is
listed as # Not carried over: comments at the top of the file. Exporting a design and importing the
file back into the same library reproduces its expressible joints on the same connectors and stocks.
A shield pigtail (the stock's bonded screens twisted and landed once) is WireViz's s wire, its prep text
the cable's notes. ?style=flow writes each connector, cable and connection set on one line, the compact
style WireViz's own examples use; the default is block style.
Bulk CSV library import (modules/csv-library)#
Library, Bulk CSV… takes a CSV or an XLSX sheet (the first one) of connectors, wire stocks, components, mechanicals, boards (PCBAs) or kits.
- Pick the file; the kind is read from a
typecolumn or from the headers, and can be changed. - Map columns. Each field of the kind has a drop-down of the file's columns (pre-filled by header
name), and a box for one value to use on every row (a kind, a currency). Batch source fills the
srcof rows that have none. - Dry run. Per row: new, already in the library (skipped, never overwritten; the fields where the file differs are shown), with Update existing records on, an update (each changed field, before and after) or unchanged, or invalid, with every reason (no source, a bad number, a duplicate id or part number, a value the library's validation refuses).
- Review. The canonical file goes to an import job; its plan is reviewed and Publish commits all the new records (and the updates) as one change set. Invalid rows are not part of it.
Update mode (the library-csv-update importer) diffs a row against the record the library has under its
id and saves the result as an edit of that record, checked like any save and made against the version the
import read (one that moved since fails the publish, nothing written). A blank cell keeps what the record has;
what the columns cannot say is kept too (a pin's signal, a board's pads and structured link paths, a kit
line's note, a wire stock's pairs and drains: a stock that is not a flat list of conductors keeps its structure
and a note says so). A row that changes nothing is reported as unchanged; a changed src alone is not a change.
Each row still needs every required column, as for a new record.
Every record needs a src. Templates (one click each in the dialog; templateCsv(kind) in the module)
have the canonical columns and one worked example row. Columns, in order:
- connectors:
type, id, label, family, gender, part_number, pins, pin_labels, construction, contact_rating_a, aliases, src+ cost columns.pinsis a count or ids separated by semicolons. - wires:
type, id, label, part_number, manufacturer, spec_ref, conductors, colours, area_mm2, material, od_mm, shield, src+ cost. Conductors arec1..cNin the colour order;shieldis none, foil, braid, spiral or tape. - components:
type, id, label, kind, category, value, part_number, mpn, manufacturer, package, tolerance, terminals, src+ cost. - mechanicals:
type, id, label, kind, part_number, revision, src+ cost. - boards:
type, id, label, part_number, revision, build, kicad_project, status, terminals, terminal_labels, links, src+ cost.terminalsis ids separated by semicolons (or a count);linksis declared continuity,from>toorfrom>to:viaseparated by semicolons. - kits:
type, id, label, sku, contents, src+ cost.contentsiskind:idorkind:id:quantityseparated by semicolons (connector:de9-male;mechanical:jackscrew-4-40:2). - cost columns:
unit_cost, currency, cost_per, cost_breaks, moq(breaks as10:0.80;100:0.60).
A blank id is derived from the name. A file uploaded straight through Import… must already use the
canonical headers (a type column and the field keys); the mapping dialog writes that file. An XLSX is read
without a dependency (stored or deflated zip, shared or inline strings; formulas show their cached value).
Connection list → design#
Library, Connections CSV… makes a design from a two-column from/to pin CSV: one row per
connection, each end written part.pin (J1.3, or J2:A.1 where a pin id has a dot). Optional
columns: core (with a wire stock) and note.
- Pick the file. A part is a connector instance; the dialog lists each part with the connector it resolved to (a part named after a library connector's id, label or part number resolves by itself) and lets you pick the rest. A part nothing names is never guessed: its rows are left out.
- Carried on. Direct pin to pin (the default) makes a joint per row (a loopback, a patch
lead). With a wire stock the rows are conductors of one segment of it, in order or by the
corecolumn (a conductor's path, colour or 1-based number);fromlands on enda,toon endb. - Dry run. The rows that become joints, and each row left out with its reason (a pin the connector lacks, an unknown part, a repeated pair, a conductor already used, none left).
- Review sends the file and these choices to the
connection-listimport job; Publish commits the proposed design (new id; one the catalog has is kept) as one change set. The same importer takes the optionsparts(JSON: part → connector id),design,labelandwire.
Costing#
A library record may carry an optional price (additive; records without one are unpriced):
"cost": { "unit": 0.42, "currency": "USD", "per": "each",
"breaks": [{ "minQty": 100, "unit": 0.35 }], "moq": 25, "src": "quote 2026-10-01" }
unitis per piece, or per metre for a wire stock (persays otherwise);currencyis an ISO code and defaults to the hub's;breaksgive the unit price fromminQtyup (the base price applies below the first);moqis information. Edited in the Library under Cost, the breaks as a small table (one row per break, with its saving against the base price);validateDbchecks it.- Engineering settings, Costing: the hub's
currencyand alabourRatePerHour. They are part ofdata/settings/engineering.json(costing). - A design records
labourMinutes(hand labour for one cable; the model has no per-operation times, so it is one figure per design; edited at the foot of the notes panel). Per-operation times (cut, strip, crimp, solder) are not in the model: they would be a shop's standard work, so they are an idea for a module, as are live supplier pricing and FX rates (the base stays deterministic and offline). - The BOM (sheet, markdown,
bom.csv, the XLSX) gains unit and extended cost per line, a Cost section with materials, labour and the total for one cable, and, for a build quantity (the field beside the BOM,?quantity=Non the API), the total for the build with quantity breaks read at line quantity x N. - Nothing is printed when no part is priced and no labour recorded. A part with no price is listed as unpriced and the total says it is a floor. Prices in another currency than the hub's are shown but left out of the total (there are no exchange rates). Labour with no rate is shown but not priced.
- A module may supply live pricing by writing
coston records;deriveCost(@wirehub/docs) is pure.