# netwerk.py - het 12,8 V-net van de klimaatmodule met de knooppuntenmethode
import numpy as np

RHO = 0.0172                                    # koper, Ω·mm²/m


def kabel(lengte, doorsnede):
    """Weerstand van een kabel met plus- en minader (heen en terug), in Ω."""
    return 2 * RHO * lengte / doorsnede


knopen = ["V", "L1", "L2", "P", "D"]            # verdeelrail, lampen 1 en 2, pomp, dakmotor
takken = [("V", "L1", kabel(4.0, 6)), ("L1", "L2", kabel(1.2, 6)), ("L2", "V", kabel(5.0, 6)),
          ("V", "P", kabel(3.0, 1.5)), ("V", "D", kabel(6.0, 2.5))]
bronnen = [("V", 13.30, 0.020), ("V", 13.10, 0.025)]              # batterij A en B: U (V), R met kabel (Ω)
lasten = {"L1": 7.42, "L2": 7.42, "P": 1.00, "D": 1.84, "V": 0.62}  # stroom per verbruiker (A)


def los_op(takken):
    k = {naam: i for i, naam in enumerate(knopen)}
    G = np.zeros((len(knopen), len(knopen)))
    i = np.zeros(len(knopen))
    for a, b, R in takken:                         # elke weerstand stempelt vier plaatsen
        G[k[a], k[a]] += 1 / R
        G[k[b], k[b]] += 1 / R
        G[k[a], k[b]] -= 1 / R
        G[k[b], k[a]] -= 1 / R
    for a, U, R in bronnen:                        # bron met weerstand: 1/R op de diagonaal, U/R rechts
        G[k[a], k[a]] += 1 / R
        i[k[a]] += U / R
    for a, I in lasten.items():                    # een verbruiker trekt stroom uit zijn knoop
        i[k[a]] -= I
    return np.linalg.solve(G, i)


v = los_op(takken)
for naam, V in zip(knopen, v):
    print(f"knoop {naam:2s}: {V:7.3f} V")
for a, b, R in takken:
    I = (v[knopen.index(a)] - v[knopen.index(b)]) / R
    print(f"kabel {a:2s}-{b:2s}: {I:6.2f} A, val {abs(I) * R:.3f} V = {abs(I) * R / 12.8 * 100:.1f} % van 12,8 V")
IA, IB = [(U - v[knopen.index(a)]) / R for a, U, R in bronnen]
print(f"batterijen: {IA:.2f} A + {IB:.2f} A = {IA + IB:.2f} A; verbruikers samen {sum(lasten.values()):.2f} A")

v2 = los_op([t for t in takken if t[:2] != ("L2", "V")])    # de ringkabel L2-V breekt
print(f"zonder ring: L1 {v2[1]:.3f} V, L2 {v2[2]:.3f} V (val tot L2: {(v2[0] - v2[2]) / 12.8 * 100:.1f} %)")
