/** * Voltmeter — probe component that displays the voltage between V+ and V-. * * For DC nets the display is a single scalar (e.g. "3.300 V"). For nets * with AC content (reflected in `.tran` `timeWaveforms`) the display shows * RMS prominently with peak and DC underneath — the convention of real * bench DMMs in AC-V mode. */ import { useMemo } from 'react'; import { useElectricalStore } from '../../store/useElectricalStore'; import { useSimulatorStore } from '../../store/useSimulatorStore'; import { buildPinNetLookup, readVoltmeter } from '../../simulation/spice/probes'; import { BOARD_PIN_GROUPS } from '../../simulation/spice/boardPinGroups'; interface VoltmeterProps { id: string; } export function Voltmeter({ id }: VoltmeterProps) { const nodeVoltages = useElectricalStore((s) => s.nodeVoltages); const converged = useElectricalStore((s) => s.converged); const error = useElectricalStore((s) => s.error); const timeWaveforms = useElectricalStore((s) => s.timeWaveforms); const wires = useSimulatorStore((s) => s.wires); const boards = useSimulatorStore((s) => s.boards); const reading = useMemo(() => { const groundPins = boards.flatMap((b) => (BOARD_PIN_GROUPS[b.boardKind] ?? BOARD_PIN_GROUPS.default).gnd.map((pin) => ({ componentId: b.id, pinName: pin, })), ); const vccPins = boards.flatMap((b) => (BOARD_PIN_GROUPS[b.boardKind] ?? BOARD_PIN_GROUPS.default).vcc_pins.map((pin) => ({ componentId: b.id, pinName: pin, })), ); const netLookup = buildPinNetLookup(wires, groundPins, vccPins); return readVoltmeter( { id, metadataId: 'instr-voltmeter', properties: {} }, netLookup, { nodeVoltages, branchCurrents: {}, converged, error, solveMs: 0, submittedNetlist: '', pinNetMap: new Map(), analysisMode: timeWaveforms ? 'tran' : 'op', timeWaveforms, }, timeWaveforms, ); }, [nodeVoltages, wires, boards, id, converged, error, timeWaveforms]); const color = reading.stale ? '#666' : '#ffa500'; const height = reading.ac ? 78 : 60; return (