← Open EMC  ·  first project · open-source, local-first

EMC-Assist — find conducted-EMI risk before the lab.

Open-source, local-first tooling for conducted-EMI pre-compliance workflows: model PCB parasitics, generate LISN and cable-aware LTspice testbenches, run them in your local LTspice, compare EMI filter variants, parse .raw/.log results, and document risks before the lab. A deterministic engineering core — with an optional, opt-in LLM-assisted review layer on top. Results are engineering diagnostics, never certification.

100% local — schematic never leaves the machine Apache-2.0 open source PCB parasitic modelling LISN / cable-aware testbenches local LTspice run variant comparison & ranking min·typ·max corner sweep pre-compliance reports
Independent open-source project. LTspice is user-supplied and runs locally — never bundled, hosted, or modified. Results are pre-compliance diagnostics, not certification.
Part of the Open EMC initiative

The first project under Open EMC

Open EMC is an open-source initiative for transparent, local-first EMC tooling. EMC-Assist is its first concrete tool — a conducted-EMI workflow for LTspice-based simulations. The deterministic core runs entirely on your machine, with an opt-in LLM layer on top.

← Explore the Open EMC initiative
The problem

The ideal simulation is not the real board

A clean LTspice schematic looks reassuring — and omits almost everything that actually shapes conducted emissions. EMC-Assist exists to make those omitted effects visible early, as engineering hypotheses to test, while changes are still cheap.

Real boards carry parasitics

Trace inductance, via ESL, capacitor mounting effects, plane coupling and filter Q create resonances the ideal schematic never shows.

Cables & return paths matter

The LISN, the input cable and the return path set what an EMI receiver would actually measure — not the bare DUT.

Lab iterations are expensive

Chamber time and re-spins compound. Surfacing likely risks before the booking turns blind guesses into targeted checks.

Workflow

A run, end to end

A deterministic spine writes an auditable artifact at every stage — nothing is a black box. After simulation, an LLM panel fans out over the result, then converges into one diagnosis.

01 · Import.asc / .cir 02 · Topologynet roles 03 · Parasiticsmin·typ·max / net 04 · TestbenchLISN+cable+inj 05 · Variants×3 min/typ/max 06 · SimulateLTspice + detectors
optional · when enabled, the analysis fans out to the LLM review panel — off by default ↓
simulation output
.raw · metrics · quasi-peak-like detectors
fan‑out →
dcdc
filtering
power_integrity
decoupling
parasitics
stackup
high_speed
mixed_signal
ic_vendor
layout_risk
signal_map
11 specialists run in parallel · each one focused LLM call · redacted payloads only
→ cluster →
orchestrator
clusters findings
synthesiser
one diagnosis
diagnosis → report
conf 70% · cited

A pre-composition LISN-mode agent also shapes stage 04 before simulation. The deterministic core runs with or without the LLM layer — it is an assistant, never the source of truth.

Key features

What's inside

A deterministic engineering core, with an optional LLM layer bolted on top — never the source of truth.

Per-net parasitic injection shipped

Every net gets a parasitic: shunt-C universally, series R+L+C where the topology allows a clean cut. Min·typ·max bands, project overrides, and an opt-in LLM negligibility screen.

Corner sweep shipped

Parasitics are uncertain, so we sweep them. Each run produces ranked min/typ/max variants — an honest spread, not a single "certain" number.

Quasi-peak-like diagnostic metrics shipped

Peak, quasi-peak-like (meter-time-constant model) and average diagnostic metrics, compared against a configured reference curve — an uncalibrated pre-compliance diagnostic, not a certified-receiver reading.

11 specialist agents opt-in · experimental

One focused LLM call per area (DC/DC, filtering, layout, decoupling, parasitics…), plus a pre-composition LISN-mode agent, an orchestrator and a diagnostic synthesiser.

Local RAG opt-in · experimental

Curated EMC seed rules, local embeddings and a pure-numpy vector index — no FAISS/Chroma, no cloud index. Every rule carries a source or is flagged as an engineering estimate.

Copyright-safe redaction shipped

Outbound LLM payloads carry only rule_id + source_id + our summary + a ≤200-char excerpt. Full vendor text and your netlist never leave the machine.

Auditable reports shipped

Markdown / HTML (PDF optional) with an assumptions table, parasitics table, before/after, a risk list, cited sources and a pre-compliance disclaimer.

Desktop UI shipped (M3)

A pywebview shell over the same service core: Projects → Report, with stage gating, live logs, the detector spectrum and a stale-data guard.

Local-first & private shipped

LTspice runs locally and is never bundled. Cloud LLM is opt-in and key-gated; with it off, no network calls happen under any action.

Schematic import & topology shipped

Import an .asc/.cir, parse R/L/C/V/I/X/M/D + .model/.param/.tran, and derive net roles (power / switch / signal / return) for the analysis.

AI: suggest negligible opt-in · experimental

An opt-in LLM negligibility screen pre-deselects nets that won't move the conducted band — you keep the final say. Key-gated; deterministic otherwise.

AI: re-evaluate values (RAG) opt-in · experimental

One batched LLM+RAG pass refines every net's R/L/C into citation-backed min·typ·max. Preview → review → apply; the deterministic prior is the fallback.

Time-domain waveform analyzer shipped

Two time-aligned panels: the LISN-measured V(meas) over a comparison trace (load current by default; four more LLM/heuristic-picked for EMI relevance).

Quasi-peak at frequency & sweep shipped

Quasi-peak-like diagnostic at a single frequency with margin to the configured reference curve, or a full sweep across the conducted band (150 kHz–30 MHz) — read straight off the run's .raw.

Standardized recommendation JSON shipped

Every finding carries problem · evidence · proposed change · value range · assumptions · limitations · sim/measurement requirement · confidence · severity · sources.

Accept / reject feedback loop shipped

Decide on each recommendation; decisions persist to decisions/*.json and flow into the report's decision log.

Simulation-settings review shipped

A deterministic, free check of your .tran window/timestep against the conducted band and switching edges — review proposed settings before they apply.

Honest-data stale guard shipped

Edit any upstream input and the whole downstream chain is flagged stale; Results / Findings / Report refuse to present old numbers as current.

One service core, two front-ends shipped

A typed service/ layer is the product; the CLI and the desktop app are thin adapters over it, with a structured logging seam and offline schema validation.

LTspice .asc visualisation export shipped

The composed testbench is also emitted as an .asc you can open in LTspice to eyeball the LISN + cable + injection wiring.

Parasitics & testbench

Every net modelled — then wired into a LISN testbench

PCB parasitics dominate conducted EMI and they're uncertain — so the tool estimates a min·typ·max band for every net from role-tuned geometry, cites a rule (or marks it an engineering estimate), injects them, and assembles a LISN testbench around your circuit. An LLM can screen out negligible nets and refine the values against the knowledge base — both opt-in, both reviewable.

Estimated structures — case_003 (real, min·typ·max)

StructureTypemintypmaxconfsrc
trace R 25×0.5 1ozR mΩ20.225.331.6highR001
trace L iso 25×0.5L nH12.625.237.8medR002
trace C Z0 25–50C pF2.343.354.35highR004/5
plane-pair C 100mm²C pF1.902.382.97medR012
via L h1.6 d0.3L nH0.911.301.82medR010
loop self-resonanceMHz438548685highR030

Models cover trace R/L/C, vias, plane pairs, cables and capacitor ESR/ESL/SRF. Injection: a shunt-C on every net, plus a series R+L+C where the net is a clean point-to-point cut; each L gets a Q-damping resistor so tiny pF/nH tanks don't blow up transient time. --parasitics-report-only keeps estimates in the report but out of the sim; project overrides pin any value.

AI: suggest negligible

The opt-in negligibility screen reads the per-net plan and pre-deselects nets that won't change the conducted band. For case_003 the 17 LTC7800 controller-pin nets are skipped, leaving 14 power/switch/signal nets.

AI: re-evaluate values (RAG)

A single batched LLM+RAG call turns each net's rule-of-thumb band into a citation-backed min·typ·max. You review the proposals (with their cited sources) and apply only the typ overrides — no second call, full audit kept.

Injection summary — testbench.cir

V_RAIL → LISN+ → cable → [TRACE_RLC] → DUT (31 nets) → LISN- · DM+CM probes

Series RLC
6 nets
Shunt-C
7 nets
Dropped · user
17 nets
Dropped · AI
0 nets
Input-rail inj.
1 TRACE
LISN
dual DM+CM

Signals probed Vout=V(OUT), Vin=V(IN) · supply VIN ↦ LISN · return 0 ↦ LISN · wiring/parasitics/signal audits all green

Diagnostics · real data

The conducted-emissions spectrum

A real per-frequency quasi-peak-like detector sweep from the bundled case_003 example — an LTC7800 buck (12 → 3.3 V) — against a configured reference curve. The detector flags a low-frequency quasi-peak-like exceedance above that reference curve in this simulation: a pre-compliance hypothesis to confirm on the bench.

020 4060 80100 dBµV 150k1 MHz 10 MHz30 MHz QP +12.9 dB over @ ~177 kHz
QP ≈ AVG · V(meas) QP limit (configured reference) AVG limit

Real artifact: results/spectrum.json · 96-point sweep · 150 kHz–30 MHz · trace V(meas). Margins are pre-compliance estimates against a configured reference curve — not a calibrated lab measurement.

Optional LLM-assisted reviewopt-in · experimental

An optional review layer — that cites its sources

Entirely optional and off by default. The deterministic core produces the result on its own; when you opt in and supply a key, this experimental layer reviews it. After simulation, 11 area specialists each produce structured recommendations; an orchestrator clusters them and a synthesiser writes one top-level diagnosis. A pre-composition LISN-mode agent shapes the testbench. Each is a single focused call — no autonomous loops, and the engineer keeps the final say.

dcdcfiltering power_integritydecoupling parasiticsstackup high_speedmixed_signal ic_vendorlayout_risk signal_map + orchestrator + synthesiser + LISN-mode (pre-compose)

Diagnosis — case_003, real

“Switch-node (hot-loop) dv/dt likely dominates conducted EMI, with input-filter resonance a secondary contributor.” The simulation shows differential-mode amplitude far above common-mode (20.85 V vs 10.40 V) — consistent with DM-driven emission from a high-dv/dt node.

confidence 70%LLM-synthesised cites SRC-045, SRC-082hypothesis · verify on bench

What we send to the cloud (when enabled)

Always sentNever sent
rule_id · source_idyour schematic / netlist
our own summaryfull vendor document text
≤200-char excerpt*net names (redacted)

*only from permissively-licensed sources. Every outbound payload is logged to results/llm/*.jsonl. Cloud LLM is off by default.

A slice of the real findings for case_003 — 11 areas, ~37 recommendations:

HIGHdcdcDifferential-mode emissions are dominant in the simulation (dm_peak > cm_peak).conf 70%
HIGHpower_integrityLikely LC resonance near 156 kHz amplifying conducted noise.conf 60%
HIGHlayout_riskUnknown hot-loop area and loop inductance around the switch node and input decoupling.conf 30%
Local-first privacy model

What stays on your machine

By default, nothing leaves your computer. The optional cloud-LLM layer is key-gated and off until you turn it on — and even then it only ever sees a redacted, structured summary, never your design files.

⌂  Stays local — always
schematic
netlist
.raw / .log results
generated testbench
project files

With cloud LLM off, no network calls happen under any action.

↗  Optional LLM payload — only when enabled
redacted structured summary
cited snippets (≤200-char, permissive sources)
metrics
never the full schematic / netlist by default

Every outbound payload is logged to results/llm/*.jsonl — a privacy audit trail you can inspect.

Open-source knowledge model

No hidden knowledge dump

EMC-Assist does not ship a hidden knowledge dump. The core is open source, and users can index sources they are legally allowed to use.

The core is open source

You can read exactly how each parasitic value is estimated, and where the result is an engineering assumption rather than a measurement.

Bring your own sources

Index the references you're legally allowed to use. No bundled scraped RAG dump; no paid standards shipped inside the tool.

Knowledge stays user-controlled

Every rule carries a source or is flagged as an engineering estimate — guidance is never presented without showing where it came from.

Architecture

One service core, two front-ends

A typed service/ layer is the product; the CLI and the desktop app are thin adapters over it. The deterministic spine writes an auditable artifact at every stage; the agent, RAG and LLM layers sit on top — opt-in, and never the source of truth. Everything runs locally: LTspice is a local subprocess, and only redacted, structured payloads ever leave the machine, only when cloud LLM is explicitly enabled.

FRONT-ENDS · THIN ADAPTERS CLI · emc-assistantargparse over service/ Desktop app · pywebviewApi bridge → service/ service/ — application coreuse-cases (project · context · parasitics · testbench · simulate · report · pipeline) · resolvers · CommandOptions DETERMINISTIC SPINE · AUDITABLE ARTIFACT PER STAGE netlist.cir parse · topology parasiticsper-net R·L·C bands testbenchLISN+cable+inject ltspicerunner · .raw/.log resultsdetectors · metrics · rank reportsmd · html · pdf OPT-IN LLM LAYER · ASSISTANT, NOT SOURCE OF TRUTH agents/11 specialists + orchestrator + synthesiser knowledge/ — RAGcurated rules · numpy vector index llm/ — provider seambudget cap · copyright redaction EXTERNAL · LOCAL FIRST LTspice — local subprocessuser-supplied · batch -b -Run · never bundled / hosted Cloud LLM — opt-in, key-gatedredacted structured egress · off by default · budget-capped runs redacted only

service/ is the product

One typed application core — a plain function per use case returning a result dataclass. Both front-ends are thin adapters, so behaviour can't drift between the CLI and the app.

Auditable spine

Every stage writes a JSON/SPICE artifact under generated/ · results/ · reports/ — nothing is a black box, and the whole chain is reproducible from the inputs.

Local-first egress control

The deterministic core needs no network. Cloud LLM is opt-in and key-gated; every outbound payload is redacted (rule_id+summary, ≤200-char excerpt) and logged to results/llm/*.jsonl.

Offline schema validation

A local referencing.Registry resolves every cross-$ref offline, so all artifacts are schema-validated without touching the network.

Structured logging seam

Components log under emc_assistant.<area> to a console handler, an optional per-run JSONL file, and a UI hook — replacing ad-hoc prints.

Where it's going (M11)

A localhost service + thin client: the pipeline runs out-of-process so a UI crash can never lose a run, with pull-based logging and a content-aware freshness model. The service/ layer stays the core.

The desktop app

Screens, on real case_003 data

The pywebview shell reads the very same artifacts shown above. Below: the full app — left rail with pipeline gating, topbar and the active screen — then each screen on its own. (Renderings reproduce the live screens with real case_003 values.)

EMC Assistant — case_003_DCDC_eval — Results
Project / case_003_DCDC_eval / Results
topology DC/DC buckVin/Vout 12 / 3.3 Vpipeline report
🔒 cloud LLM OFF ⌘S · Save
Diagnostic · results/diagnostic.json · LLM · conf 70%

Switch-node (hot-loop) dv/dt likely dominates conducted EMI; differential-mode amplitude far exceeds common-mode.

DM dominantsimulated only
Band peak
47.1 dBµV
DM peak
20.85 V
CM peak
10.40 V
Corner span
~1.0 dB

↓ the detector spectrum, waveform analyzer and corner-variant ranking follow in the live screen

06 · Results — case_003_DCDC_eval
Diagnostic · results/diagnostic.json · LLM

Switch-node dv/dt likely dominates conducted EMI…

conf 70%DM dominant
Band peak
47.1 dBµV
DM peak
20.85 V
CM peak
10.40 V
Corner span
~1.0 dB

Corner ranking: 11 variants · worst par-trace-R…max 48.10 dBµV · baseline 47.08

03 · Parasitic selection
31 nets14 included17 skipped0 overrides
NetRoleTypeR mΩL nHC pF
N003switchseries-RLC2.74.621.07
OUTpowershunt-C7.623.44.02
N007signalseries-RLC20.219.32.68
MP_01signalshunt-C20.219.32.68

Audit → 6 series · 7 shunt · 17 dropped (user) · 1 input-rail TRACE_RLC

04 · Testbench review — case_003_DCDC_eval

V_RAIL → LISN+ → cable → [TRACE_RLC] → DUT (31 nets) → LISN- · DM+CM probes

composed
Wiring audit
Supply VIN ↦ LISN ✓
Return 0 ↦ LISN ✓
Cable · default
LISN · dual DM+CM
Input-rail · 1 TRACE_RLC
Parasitics audit
Series RLC · 6 nets
Shunt-C · 7 nets
Dropped user · 17
Dropped AI · 0
Signal audit
Vout · V(OUT)
Vin · V(IN)

Actions: View testbench.cir · Continue to run → (auto-starts the pipeline)

07 · Findings & recommendations
Open 37Accepted 0Rejected 0All 37
HIGHfilteringInput LC may be undamped; DM emissions dominate.
HIGHdecouplingBand peak suggests insufficient HF bypass near the IC.

Accept / reject each → persisted to the report's decision log.

Honest-data guard
These results are out of date. An input changed since this run — re-run the pipeline to refresh.  Re-run pipeline →

Edit any upstream input and the whole downstream chain is marked stale on the rail; Results, Findings and Report dim their numbers and show this banner. Stale data is never presented as current.

Versions & roadmap

Where it is, where it's going

Cloud model

OpenAI gpt-5-mini — opt-in, key-gated, budget-capped. Deterministic fallback when off.

Embeddings

Local sentence-transformers (POC) behind a pluggable interface; pure-numpy vector index.

Simulator

Your local LTspice (e.g. 26.0.2) — discovered, never bundled, never hosted.

M0 – M2.x
Deterministic core + LLM layer done

Schematic → testbench → variants → LTspice → metrics → ranking → report; per-net parasitics, 11 agents, RAG, redaction, CISPR-like diagnostic metrics and configured reference curves.

M3
Desktop UI done

pywebview shell over the service core — Projects → Report wired to real artifacts, with the stale-data guard.

M10
CM-coupling model planned

CSTRAY → earth, so the common-mode metrics and plot carry a real deterministic signal.

M11
UI rebuild planned

From-the-studs remake: localhost service + thin client, out-of-process pipeline, content-aware freshness, large-.raw streaming, pre-run cost/privacy gate.

M12
Live Lab Assistant planned

Overlay a live EMI-receiver spectrum on the simulated prediction; real-time attribution to a specific parasitic.

M13
Engineer Training planned

Your estimated→corrected overrides become opt-in, federated, redacted training signal — the tool improves with use.

To add & improve

The honest backlog

What's known to be missing or rough, kept in the open. Everything below is planned or a tracked caveat — not yet shipped.

Selectable detector + narrow-harmonic accuracy planned

The canonical receiver-like sweep (Mode 3, 128 pts) under-reads narrow harmonics that fall between swept points. Make detector mode / start-skip / point density user-selectable, and root-cause the skip anomaly.

Schematic-understanding agent M4

The tool netlists but doesn't yet understand the schematic — net roles are heuristic. Label power stage, high/low-side switches, SW node, hot loop and rails as user-confirmable, sourced hypotheses.

EMI-filter design / optimization agent M4

Diagnose DM/CM noise from the detector result, size a π-filter / CM choke (banded, with Y-cap leakage + damping guards), and close the loop: inject → re-simulate → adjust to meet the limit.

Device-aware sim-setup agent M4

Infer the switching-edge rate from the FET part / topology + KB, so fast-edge devices get a device-aware timestep verdict without the user supplying a rise time.

Variant-review / proposal agent M4

Review whether the min/typ/max corner sweep covers the uncertainty and propose additional sensitivity / what-if variants as an accept/skip list — additive only, never replacing the deterministic baseline.

Conversational parasitics-strategy chat M5

Direct strategy in natural language ("add a series L to every net with a 10 pF shunt"); the LLM proposes RAG-grounded per-net edits as a reviewable diff — never a silent mutation.

Common-mode coupling model M10

Opt-in, dual-LISN-only stray capacitance to earth from high-dv/dt nets, so the CM metrics and CM detector plot carry real deterministic signal (today they exist but are inert).

Security & privacy hardening review M9

A cross-cutting assurance pass before wider distribution: redaction-path audit + outbound-payload guard, key-never-logged, bridge path-traversal review, parser fuzzing, CSP, and a pip-audit scan.

UI rebuild — out-of-process M11

Localhost service + thin client: crash-isolated runs, pull-based log streaming, content-aware freshness, large-.raw streaming, a faithful per-net testbench render, and a pre-run cost/privacy gate.

Transient-event detection & auto-window planned

Detect max |di/dt| / turn-on inrush and auto-size the .tran window so a slow turn-on event isn't truncated — distinct from the steady-state conducted-EMI run.

.raw fastaccess + multi-LISN CM planned

Support LTspice fastaccess-format .raw and a real two-LISN V(CM) (today single-LISN V(CM) is a placeholder).

Pro & layout tracks M6 / M7

Project history beyond one project, richer stack-up / cable profiles, daily/monthly budget caps (M6); layout import, parasitic extraction and radiated-risk estimation (M7).

Demo workflow

A worked example, end to end

The bundled case_003 example walks the whole pipeline on a DC/DC buck converter — so you can see the shape of a run before pointing it at your own project.

01 · circuit

DC/DC converter + input cable

A buck converter (12 → 3.3 V) with an input cable and a LISN at the supply — the conducted-EMI measurement setup, in simulation.

02 · model

Parasitic sweep

Per-net min·typ·max parasitics are estimated and injected, then swept so the result is an honest spread rather than a single "certain" number.

03 · compare

Filter variants

EMI filter variants are compared and ranked against the configured reference curve to show which direction reduces risk.

In this example the diagnostic flags a low-frequency exceedance above the configured reference curve in this simulation. That is a pre-compliance hypothesis, not a verdict — it tells you where to look on the bench, and requires lab verification.
Scope

What EMC-Assist is not

Being clear about the boundaries is part of being honest. EMC-Assist is a pre-compliance engineering aid — it is deliberately none of the following.

✕  Not a certified EMC receiver

The metrics are quasi-peak-like diagnostics, not a calibrated CISPR-16 receiver reading.

✕  Not a replacement for lab testing

Every result is an engineering hypothesis that requires laboratory verification.

✕  Not a standards-compliance tool

It does not certify compliance with any standard and ships no paid standards.

✕  Not an official LTspice plugin

Independent project. LTspice is user-supplied and runs locally; it is never bundled, hosted, or modified.

✕  Not a schematic / layout editor

It reads your netlist and composes a testbench — it does not draw or edit your board.

✕  Not a cloud SaaS

Local-first by default. There is no account, no subscription, and no required cloud service.

Getting started

Run the demo locally

The shape of a first run. See the documentation for exact, verified commands — the steps below are an outline, not copy-paste commands.

Outline · example placeholders
  1. Clone the repository
  2. Install the Python package
  3. Point EMC-Assist at your local LTspice install
  4. Run a bundled demo project
  5. Open the generated pre-compliance report
You'll need
LTspiceuser-supplied · local
Pythoncore package
Cloud LLMoptional · off by default
Networknot required for a run

The deterministic core runs with the LLM layer entirely off — it is an assistant, never the source of truth.

Pre-compliance only. Every output is an engineering hypothesis requiring laboratory verification — never a guarantee that a design will pass formal EMC. Simulation does not replace accredited EMC laboratory measurement. The tool speaks in “reduces risk”, “may improve”, “requires verification”. Independent open-source project — LTspice is user-supplied and runs locally; results are engineering diagnostics, not certification.