Tool for composable circuit simulation?

Here is a seemingly working example.
Moving the equations definition to before the parameter definition makes the ifelse evaluate OK.
I guess that there are still problems left here…
To go back to your question about how the switches are defined, I guess it would be better to be able to define the state (open/closed) with parameter when the ODAEProblem is defined? Not sure if that would work with the equations being defined as they are now though…
Anyway, code below, laced with quite a few debug printouts in the IdealSwitch
I realise the isequal(isClosed,True) is redundant at start, but it is needed (but failing)
after the @parameter step.

using Revise
using ModelingToolkit
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Electrical: OnePort, Ground
using OrdinaryDiffEq
using Plots
using IfElse: ifelse

@parameters t

# No switch... need to define that.

@component function IdealSwitch(; name, isClosed=true)
    println("Creating switch, isClosed=$(isClosed)")
    println(" Before param assign: $(isClosed)  -> t? $(isequal(isClosed,true)) -> f? $(isequal(isClosed, false))")
    println("typeof(isClosed): $(typeof(isClosed))")
    @named oneport = OnePort()
    @unpack v, i = oneport
    @variables closed  # Dummy to include in eqs
    eqs = [ v ~ ifelse(isequal(isClosed, true), 0, v)
            i ~ ifelse(isequal(isClosed, true), i, 0)
            closed ~ isequal(isClosed, true)
    ]
    println(" eqs: $(eqs)")
    
    ps = @parameters isClosed = isClosed
    println("ps: $ps")

    # Original placement of eqs definition - ie _after_ params: here isequal always evaluate to false
    #eqs = [ v ~ ifelse(isequal(isClosed, true), 0, v)
    #        i ~ ifelse(isequal(isClosed, true), i, 0)
    #        closed ~ isequal(isClosed, true)
    #]
    #println(" eqs: $(eqs)")

    println("After param assign: $(isClosed)  -> t? $(isequal(isClosed,true)) -> f? $(isequal(isClosed, false))")
    println("  typeof(isClosed): $(typeof(isClosed))")
    println("  Switch is $(ifelse(isequal(isClosed, true), "CLOSED", "OPEN"))")
    extend(ODESystem(eqs, t, [], ps; name = name), oneport)
end

@named s_closed = IdealSwitch(;isClosed=true)
# equations(s_closed)
# @named s_open = IdealSwitch(;isClosed=false)
# equations(s_open)

@component function ConstantVoltage(; name, V = 12.0)
    @named oneport = OnePort()
    @unpack v = oneport
    ps = @parameters V = V
    eqs = [
        V ~ v
    ]
    extend(ODESystem(eqs, t, [], ps; name = name), oneport)
end

@named vcc = ConstantVoltage()
@named resistor = Resistor(R=2)
@named switch = IdealSwitch(isClosed=true)
@named ground = Ground()

eqs = [
    connect(vcc.p, resistor.p)
    connect(resistor.n, switch.p)
    connect(vcc.n, switch.n, ground.g)]

@named switch_sys = ODESystem(eqs, t;
    systems = [vcc, resistor, switch, ground])
sys = structural_simplify(switch_sys)
prob = ODAEProblem(sys, [], (0, 10.0))
sol = solve(prob, Tsit5())

plot(sol, idxs = [resistor.v, resistor.i],
    title = "Switch Demonstration",
    labels = ["Resistor Voltage" "Resistor Current"])