Adding a new element type¶
Checklist for adding a component to the palette (as done for capacitor and
generator in M3 — diff those commits for a worked example). Items marked ⚡
break loudly if forgotten (schema-drift tests); the rest fail quietly, so walk
the whole list.
Backend (src/opendss_designer/)¶
- ⚡
core/model.py— add the type to theNodeTypeliteral and its handles toNODE_TERMINALS(skipNODE_TERMINALSonly for dynamic-handle nodes like busbar). core/compiler.py— emission block incompile_circuit: filter nodes by type, build thenew <class>.<name> ...command viaelement_name()(which registers the element_map entry for results/issue mapping), useconn.node_buses[n.id]+_bus_suffixfor bus connections, andkv_bases.add()any rated kV.core/importer.py— add the OpenDSS class prefix toSUPPORTED_PREFIXESand a read-back block in_read_model_back(iteratedss.<Class>.First()/ Next(), preservebusNodessuffixes,wire()terminals tobusbar_for()).core/validate.py— extend the kV-consistency check if the element declares a voltage; add any element-specific structural checks.
Frontend (frontend/src/)¶
- ⚡
types/circuit.ts— add to theNodeTypeunion (mirror of model.py). lib/defaults.ts—defaultParams()case (name prefix + sensible params) andNODE_SIZEentry.lib/fields.tsx—FIELDSentry; drives both the properties panel and the spreadsheet tab. If the element can follow a loadshape, give it aloadshapeparam withkind: 'loadshape'(renders the shape-library dropdown) and appendshape_ref(p, n.id)to its compiler command (M5).components/nodes/<X>Node.tsx— symbol component: useuseSymbolRotation,rotatedBox,SymbolSvg,rotatePositionfromnodes/common.tsxso rotation works; addVoltageBadge(bus-connected) orElementBadge(series/shunt with element results).components/EditorCanvas.tsx— register innodeTypesand add a letter toPLACE_KEYS.components/Palette.tsx— palette item with icon + the samekbdletter. (Taken letters: S B T K L C G P A, plus W/E/R for modes.)lib/layout.ts— if it's a 1-terminal shunt device, add it toSHUNT_TYPESso imports hang it under its busbar; 2-terminal series devices needorientedEdges/alignDevicesBetweenBuseshandling.store/circuitStore.ts— add the name prefix toNAME_PREFIX(copy/paste renaming).
Tests¶
- ⚡
tests/fixtures/full-circuit.oneline.json— add a wired, solvable instance of the element.test_schema_fixture.py:: test_fixture_covers_every_typefails until you do; the same fixture drives the frontend round-trip test and the e2e solve test. tests/test_schema_fixture.py— add the expectednew <class>.<name>fragment totest_fixture_compiles_cleanly.tests/test_import_roundtrip.py— extend the round-trip coverage.
Then: pytest, npm test, npm run e2e, and update FUTURE_IMPROVEMENTS.md.