{"openapi":"3.1.0","info":{"title":"EnergyPlanner API","version":"0.0.1","description":"Building electrical & energy-system planner by G.T. GmbH (Berlin). One JSON model per project describes a low-voltage switchgear assembly: enclosure, rails, devices, conductors, network and thermal data. Everything else — conductor list, loss balance, temperature rise and derating, impedances and the proofs A–D, bill of material, the German Projektmappe and the assembly plan as SVG — is derived from that model on request, never stored by hand. Agents read the model, propose changes as RFC 6902 JSON-Patch, and every write is schema-validated, invariant-checked and committed to git. This is a planning tool: sign-off, Stückprüfung and grid registration remain with the Elektrofachbetrieb."},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"User access key. Private projects require authentication for reads and writes; editor role required for PUT/PATCH."}},"schemas":{"def-0":{"additionalProperties":false,"description":"Model of one building: its floors, its grid connection, its generation and storage, and its distribution boards. Every table of the German Projektmappe (Leiterliste, Verlustbilanz, Erwärmung, Impedanzen, Stückliste) is derived from one board of this model, never stored.","type":"object","required":["schemaVersion","meta","gebaeude","netz","erzeugung","verteiler","konstanten"],"properties":{"schemaVersion":{"type":"number","enum":[2]},"meta":{"additionalProperties":false,"type":"object","required":["id","name","ausgabe","stand"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"type":"string"},"address":{"type":"string"},"bauherr":{"type":"string"},"ausgabe":{"type":"number"},"stand":{"type":"string"},"norm":{"type":"string"},"katalog":{"additionalProperties":false,"type":"object","required":["id"],"properties":{"id":{"minLength":1,"description":"Fassung von catalog/, an die diese Planung geheftet ist. Eine neue Normausgabe wirft eine abgeschlossene Planung damit nicht rückwirkend um.","type":"string"},"engine_commit":{"minLength":1,"description":"Git-Commit des Rechenkerns zum Zeitpunkt der Rechnung. Ohne ihn lässt sich fünf Jahre später zwar nachlesen, was gerechnet wurde, aber nicht nachrechnen.","type":"string"},"gerechnet_am":{"description":"ISO-Zeitpunkt der Rechnung.","type":"string"}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"gebaeude":{"additionalProperties":false,"type":"object","required":["typ","adresse","etagen"],"properties":{"typ":{"description":"Art des Objekts: Haus, Wohnung, Halle/Werkstatt, freistehende Station (Technikgebäude), sonstiges.","anyOf":[{"type":"string","enum":["haus"]},{"type":"string","enum":["wohnung"]},{"type":"string","enum":["halle"]},{"type":"string","enum":["station"]},{"type":"string","enum":["sonstig"]}]},"adresse":{"type":"string"},"nutzung":{"additionalProperties":false,"type":"object","required":["ereignisse"],"properties":{"ereignisse":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","name","art","von_h","dauer_h"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"minLength":1,"type":"string"},"art":{"description":"Was in dieser Zeit läuft.","anyOf":[{"type":"string","enum":["licht"]},{"type":"string","enum":["geraet"]},{"type":"string","enum":["kochen"]},{"type":"string","enum":["warmwasser"]},{"type":"string","enum":["lueftung"]},{"type":"string","enum":["dauerlast"]},{"type":"string","enum":["wallbox"]}]},"von_h":{"minimum":0,"maximum":24,"description":"Beginn in Stunden, 6.5 = 6:30.","type":"number"},"dauer_h":{"exclusiveMinimum":0,"maximum":24,"type":"number"},"leistung_W":{"minimum":0,"description":"Leistung während des Ereignisses. Fehlt sie, kommt sie aus den Stromkreisen (`kreise`).","type":"number"},"kreise":{"description":"Stromkreise, deren angeschlossene Verbrauchsstellen in dieser Zeit laufen — ihre Summe ist die Leistung.","type":"array","items":{"minLength":1,"type":"string"}},"liter":{"minimum":0,"description":"Zapfmenge Trinkwarmwasser in Litern; nur bei art \"warmwasser\".","type":"number"},"faktor":{"minimum":0,"maximum":1,"description":"Ausnutzungsgrad: wie viel der angeschlossenen Leistung während des Ereignisses wirklich fliesst. Ein Kochfeld mit 8,2 kW Anschlusswert zieht beim Kochen nicht 8,2 kW, eine Waschmaschine nur beim Heizen. Ohne Angabe 1 — dann ist Anschlusswert gleich Betriebswert.","type":"number"},"saison":{"description":"Nur in dieser Jahreszeit. Ohne Angabe: das ganze Jahr.","anyOf":[{"type":"string","enum":["winter"]},{"type":"string","enum":["sommer"]},{"type":"string","enum":["uebergang"]}]},"tage":{"anyOf":[{"type":"string","enum":["alle"]},{"type":"string","enum":["werktag"]},{"type":"string","enum":["wochenende"]}]},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"bewohner":{"minimum":0,"description":"Wie viele Menschen im Haus wohnen. Der Bedarf an Trinkwarmwasser hängt an ihnen, nicht an der Wohnfläche: fünf Menschen duschen fünfmal, ob das Haus 200 oder 300 m² hat. Ohne Angabe rechnet das Lastszenario mit dem Flächenkennwert ww_kwh_m2a und sagt das.","type":"number"},"lat":{"minimum":-90,"maximum":90,"description":"Breitengrad, Eingang für PVGIS","type":"number"},"lon":{"minimum":-180,"maximum":180,"description":"Längengrad, Eingang für PVGIS","type":"number"},"bauweise":{"description":"Tragende Bauweise. Entscheidend ist die Brennbarkeit der Baustoffe: holz, holzstaender und fertigteil (Holztafel) sind brennbar und lösen zusammen mit Schlafräumen die AFDD-Pflicht aus (DIN VDE 0100-420 §421.7); mauerwerk, stahlbeton und stahl sind nicht brennbar. Bei misch entscheidet der Raum, nicht das Gebäude.","anyOf":[{"type":"string","enum":["holz"]},{"type":"string","enum":["holzstaender"]},{"type":"string","enum":["fertigteil"]},{"type":"string","enum":["mauerwerk"]},{"type":"string","enum":["stahlbeton"]},{"type":"string","enum":["stahl"]},{"type":"string","enum":["misch"]}]},"daemmung":{"additionalProperties":false,"type":"object","required":["vorhanden"],"properties":{"vorhanden":{"description":"Hat das Gebäude eine Wärmedämmung in den Bauteilen, in denen Leitungen liegen?","type":"boolean"},"stoff":{"description":"Dämmstoff. mineralwolle ist nicht brennbar; eps, xps, pur_pir, holzfaser und zellulose sind brennbar.","anyOf":[{"type":"string","enum":["mineralwolle"]},{"type":"string","enum":["eps"]},{"type":"string","enum":["xps"]},{"type":"string","enum":["pur_pir"]},{"type":"string","enum":["holzfaser"]},{"type":"string","enum":["zellulose"]},{"type":"string","enum":["andere"]}]},"leitungen_in_daemmung":{"description":"Liegen Leitungen in der Wärmedämmung? Dann gilt Verlegeart A1/A2 statt C — die Strombelastbarkeit sinkt erheblich (DIN VDE 0298-4 Tab. 3). Eingang der Querschnittsberechnung ab Etappe 2.","type":"boolean"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"huelle":{"additionalProperties":false,"type":"object","required":["bauteile","fenster"],"properties":{"bauteile":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","name","art","schichten"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"type":"string"},"art":{"anyOf":[{"type":"string","enum":["wand"]},{"type":"string","enum":["kellerwand"]},{"type":"string","enum":["dach"]},{"type":"string","enum":["decke"]},{"type":"string","enum":["boden"]}]},"flaeche_m2":{"minimum":0,"description":"Fehlt sie, wird sie aus den Etagen geschätzt.","type":"number"},"schichten":{"description":"Leer, wenn nur der U-Wert bekannt ist.","type":"array","items":{"additionalProperties":false,"type":"object","required":["stoff","dicke_mm","lambda"],"properties":{"stoff":{"description":"Benennung des Stoffs, z. B. \"Mineralwolle\" oder \"Mauerwerk\".","type":"string"},"dicke_mm":{"exclusiveMinimum":0,"type":"number"},"lambda":{"exclusiveMinimum":0,"description":"Wärmeleitfähigkeit in W/(m·K), z. B. 0.032.","type":"number"},"im_gefach":{"description":"true = die Schicht liegt zwischen Holzquerschnitten und wird von ihnen durchbrochen; false oder fehlend = durchgehende Lage, die die Hölzer überdeckt.","type":"boolean"}}}},"u_wert":{"exclusiveMinimum":0,"description":"Vorgegebener U-Wert in W/(m²·K). Er gilt nur, wenn keine Schichten dastehen — sonst wird aus den Schichten gerechnet, und die Rechnung ist nachvollziehbar, die Vorgabe nicht.","type":"number"},"holzanteil":{"minimum":0,"maximum":0.5,"description":"Anteil der Holzquerschnitte an der Fläche, z. B. 0.12. Wirkt nur auf Schichten mit im_gefach.","type":"number"},"puffer":{"minimum":0,"maximum":1,"description":"Temperatur-Korrekturfaktor nach DIN EN ISO 13789: 1 = gegen Aussenluft, 0.6 = gegen einen gedämmten Dachraum, 0.5 = gegen Erdreich.","type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"fenster":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","stueck","breite_m","hoehe_m"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"type":"string"},"etage":{"type":"string"},"stueck":{"minimum":1,"type":"number"},"breite_m":{"exclusiveMinimum":0,"type":"number"},"hoehe_m":{"exclusiveMinimum":0,"type":"number"},"u_w":{"exclusiveMinimum":0,"description":"U-Wert des ganzen Fensters in W/(m²·K). Ohne Datenblatt bleibt er offen.","type":"number"},"rahmen":{"description":"z. B. \"Aluminium mit thermischer Trennung\".","type":"string"},"verglasung":{"type":"string"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"lueftung":{"additionalProperties":false,"type":"object","required":["luftwechsel_1h"],"properties":{"luftwechsel_1h":{"minimum":0,"description":"Über die Anlage geführter Luftwechsel.","type":"number"},"infiltration_1h":{"minimum":0,"description":"Unorganisierte Infiltration; von keiner Rückgewinnung erfasst.","type":"number"},"rueckgewinnung_pct":{"minimum":0,"maximum":100,"type":"number"},"geraete":{"minimum":0,"type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"t_innen_C":{"description":"Vorgabe der Innentemperatur, sonst 20 °C.","type":"number"},"heizgrenze_C":{"description":"Darüber wird nicht geheizt, sonst 15 °C.","type":"number"},"ww_kwh_m2a":{"minimum":0,"description":"Trinkwarmwasser je Quadratmeter und Jahr. Ohne Erhebung am Objekt eine Annahme.","type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"etagen":{"description":"Etagen von unten nach oben; leer, solange nichts eingegeben ist","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","level","name"],"properties":{"id":{"minLength":1,"type":"string"},"level":{"description":"Keller = -1, Erdgeschoss = 0, Obergeschoss = 1 …","type":"integer"},"name":{"type":"string"},"hoehe_m":{"exclusiveMinimum":0,"description":"Lichte Raumhöhe in Metern","type":"number"},"b_m":{"exclusiveMinimum":0,"description":"Eingegebene Breite. Jede Seite steht für sich — der Umriss entsteht, sobald beide da sind.","type":"number"},"l_m":{"exclusiveMinimum":0,"description":"Eingegebene Länge.","type":"number"},"flaeche_m2":{"exclusiveMinimum":0,"description":"Grundfläche der Etage in m². Aus b_m × l_m erzeugt oder von Hand eingetragen.","type":"number"},"anbauten":{"description":"Vorsprünge des Baukörpers auf dieser Etage — Terrasse, Wintergarten, Erker.","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","seite","abstand_m","breite_m","tiefe_m"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"type":"string"},"seite":{"description":"Seite des Grundrisses: sued = unten (y = 0), nord = oben, west = links (x = 0), ost = rechts.","anyOf":[{"type":"string","enum":["sued"]},{"type":"string","enum":["nord"]},{"type":"string","enum":["west"]},{"type":"string","enum":["ost"]}]},"abstand_m":{"minimum":0,"description":"Abstand von der linken bzw. unteren Ecke dieser Seite","type":"number"},"breite_m":{"exclusiveMinimum":0,"description":"Ausdehnung entlang der Seite","type":"number"},"tiefe_m":{"exclusiveMinimum":0,"description":"Wie weit der Anbau aus dem Baukörper heraussteht","type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"raeume":{"description":"Räume dieser Etage mit ihrer Nutzung. Ihre Reihenfolge ist ihre Lage im Grundriss.","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","name","art"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"type":"string"},"art":{"description":"Nutzung des Raums, nach dem geordnet, was sie an der Schutzmaßnahme ändert: bad (Wanne oder Dusche → Bereiche nach DIN VDE 0100-701), wc (ohne Dusche), kueche und hwr sind Feuchträume mit RCD 30 mA; schlafen und kind sind Schlafräume (AFDD bei brennbarer Bauweise, DIN VDE 0100-420 §421.7); balkon ist außen. sonstig trägt seine Bedeutung im Namen.","anyOf":[{"type":"string","enum":["bad"]},{"type":"string","enum":["wc"]},{"type":"string","enum":["kueche"]},{"type":"string","enum":["hwr"]},{"type":"string","enum":["schlafen"]},{"type":"string","enum":["kind"]},{"type":"string","enum":["wohnen"]},{"type":"string","enum":["buero"]},{"type":"string","enum":["flur"]},{"type":"string","enum":["treppe"]},{"type":"string","enum":["eingang"]},{"type":"string","enum":["abstellraum"]},{"type":"string","enum":["technik"]},{"type":"string","enum":["garage"]},{"type":"string","enum":["balkon"]},{"type":"string","enum":["sonstig"]}]},"marke":{"description":"Punkt im Grundriss, der diesen Raum bezeichnet. Der von Wänden eingeschlossene Bereich, in dem die Marke liegt, IST der Raum — seine Fläche wird gezeichnet, nicht eingetragen.","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"flaeche_m2":{"exclusiveMinimum":0,"description":"Gewünschte Fläche aus der Planung. Die wirkliche kommt aus dem Grundriss; die Abweichung wird gezeigt.","type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"moebel":{"maxItems":500,"description":"Furniture independent of electrical points. Validated with F001–F006.","type":"array","items":{"additionalProperties":false,"description":"Interior v1: metres, centre anchor, y up, counter-clockwise quarter turns. Bed sleeping size excludes 5 cm frame per side. Catalog and rules: GET /api/v1/interior.","type":"object","required":["id","asset","catalogVersion","xy","width_m","depth_m","rotation","color"],"properties":{"id":{"minLength":1,"type":"string"},"asset":{"anyOf":[{"type":"string","enum":["bed"]},{"type":"string","enum":["nightstand"]},{"type":"string","enum":["wardrobe"]},{"type":"string","enum":["bathtub"]},{"type":"string","enum":["toilet"]},{"type":"string","enum":["basin"]},{"type":"string","enum":["shower-square"]},{"type":"string","enum":["shower-rect"]},{"type":"string","enum":["shower-corner"]},{"type":"string","enum":["sofa"]},{"type":"string","enum":["sofa-corner"]},{"type":"string","enum":["armchair"]},{"type":"string","enum":["coffee-table"]},{"type":"string","enum":["table"]},{"type":"string","enum":["table-round"]},{"type":"string","enum":["chair"]},{"type":"string","enum":["desk"]},{"type":"string","enum":["treadmill"]},{"type":"string","enum":["exercise-bike"]},{"type":"string","enum":["elliptical"]},{"type":"string","enum":["weight-bench"]},{"type":"string","enum":["dumbbell-rack"]},{"type":"string","enum":["fireplace"]},{"type":"string","enum":["stove"]},{"type":"string","enum":["kitchen-base"]},{"type":"string","enum":["kitchen-sink"]},{"type":"string","enum":["hob"]},{"type":"string","enum":["fridge"]},{"type":"string","enum":["dishwasher"]},{"type":"string","enum":["island"]},{"type":"string","enum":["washer"]},{"type":"string","enum":["dryer"]},{"type":"string","enum":["laundry-basket"]},{"type":"string","enum":["utility-sink"]},{"type":"string","enum":["shelving"]},{"type":"string","enum":["dresser"]},{"type":"string","enum":["shoe-cabinet"]},{"type":"string","enum":["coat-rack"]},{"type":"string","enum":["bookcase"]},{"type":"string","enum":["office-chair"]},{"type":"string","enum":["staircase"]},{"type":"string","enum":["boiler"]},{"type":"string","enum":["heat-pump"]}]},"catalogVersion":{"anyOf":[{"type":"string","enum":["1.0.0"]},{"type":"string","enum":["1.1.0"]}]},"xy":{"description":"[x, y] in Metern, y nach oben, Ursprung frei je Etage","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"width_m":{"exclusiveMinimum":0,"maximum":10,"type":"number"},"depth_m":{"exclusiveMinimum":0,"maximum":10,"type":"number"},"rotation":{"anyOf":[{"type":"number","enum":[0]},{"type":"number","enum":[90]},{"type":"number","enum":[180]},{"type":"number","enum":[270]}]},"color":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"room":{"minLength":1,"type":"string"},"ascent":{"description":"Stair ascent along local +y or -y before rotation; legacy default forward. Staircases only.","anyOf":[{"type":"string","enum":["forward"]},{"type":"string","enum":["reverse"]}]},"sleeping_m":{"type":"array","items":[{"exclusiveMinimum":0,"type":"number"},{"exclusiveMinimum":0,"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2}}}},"punkte":{"description":"Verbrauchsstellen dieser Etage","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","art"],"properties":{"id":{"minLength":1,"type":"string"},"raum":{"minLength":1,"description":"Raum, in dem die Stelle liegt","type":"string"},"xy":{"description":"Lage im Grundriss in Metern — Anfang der Leitung. Fehlt, solange die Stelle noch nicht gesetzt ist.","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"art":{"description":"Art der Verbrauchsstelle. Bestimmt Vorgaben für Leistung, Phasen und Schutz.","anyOf":[{"type":"string","enum":["steckdose"]},{"type":"string","enum":["licht"]},{"type":"string","enum":["herd"]},{"type":"string","enum":["backofen"]},{"type":"string","enum":["dunstabzug"]},{"type":"string","enum":["spuelmaschine"]},{"type":"string","enum":["waschmaschine"]},{"type":"string","enum":["trockner"]},{"type":"string","enum":["boiler"]},{"type":"string","enum":["wp"]},{"type":"string","enum":["hydraulik"]},{"type":"string","enum":["heizungspumpe"]},{"type":"string","enum":["fancoil"]},{"type":"string","enum":["lueftung"]},{"type":"string","enum":["dusch_wc"]},{"type":"string","enum":["bewegungsmelder"]},{"type":"string","enum":["wallbox"]},{"type":"string","enum":["ems"]},{"type":"string","enum":["server"]},{"type":"string","enum":["aussen"]},{"type":"string","enum":["sonstig"]}]},"name":{"type":"string"},"leistung_W":{"minimum":0,"type":"number"},"phasen":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[3]}]},"anzahl":{"minimum":1,"description":"Mehrere gleiche Stellen an einem Ort, z. B. eine Vierfachsteckdose","type":"integer"},"verteiler":{"minLength":1,"description":"Verteiler, an dem diese Stelle hängt. Ohne Angabe der nächstgelegene.","type":"string"},"stromkreis":{"minLength":1,"description":"Leiter (id im Verteiler), an dem diese Stelle hängt — z. B. \"WKF10\" für den Fancoil-Kreis. Mit leistung_W zählt die Stelle im Haus als Verbraucher dieses Kreises.","type":"string"},"notstrom":{"description":"Muss im Inselbetrieb an der LOAD-Seite des Wechselrichters bleiben","type":"boolean"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"plan":{"additionalProperties":false,"type":"object","properties":{"bild":{"description":"Unterlegtes Foto oder PDF des Grundrisses, Pfad im Projektordner","type":"string"},"massstab_m_je_px":{"exclusiveMinimum":0,"description":"Aus einem bekannten Maß im Bild abgeleitet","type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"waende":{"description":"Wände dieser Etage, im Plan Editor gezeichnet","type":"array","items":{"additionalProperties":false,"description":"Eine Innenwand als Strich zwischen zwei Punkten in Metern, achsparallel. Wände trennen die Etage in Bereiche; eine Lücke in der Wand ist eine Tür und lässt den Bereich zusammenhängen.","type":"object","required":["id","von","nach"],"properties":{"id":{"minLength":1,"type":"string"},"von":{"description":"[x, y] in Metern, y nach oben, Ursprung frei je Etage","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"nach":{"description":"[x, y] in Metern, y nach oben, Ursprung frei je Etage","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"dicke_m":{"exclusiveMinimum":0,"type":"number"},"tragend":{"description":"Tragende Wand — Leitungen dürfen nicht beliebig geschlitzt werden","type":"boolean"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"netz":{"additionalProperties":false,"type":"object","required":["un_V","u0_V","sls_A","ina_A"],"properties":{"un_V":{"type":"number"},"u0_V":{"type":"number"},"fn_Hz":{"type":"number"},"form":{"type":"string"},"sls_A":{"type":"number"},"ina_A":{"type":"number"},"ik_max_kA":{"anyOf":[{"type":"number"},{"type":"null"}]},"igrid_max_A":{"type":"number"},"tarif":{"additionalProperties":false,"type":"object","required":["tag_ct","nacht_ct","nacht_von_h","nacht_bis_h","einspeisung_ct"],"properties":{"tag_ct":{"minimum":0,"description":"Arbeitspreis am Tag, Cent je kWh","type":"number"},"nacht_ct":{"minimum":0,"description":"Arbeitspreis in der Nacht, Cent je kWh","type":"number"},"nacht_von_h":{"minimum":0,"maximum":24,"type":"number"},"nacht_bis_h":{"minimum":0,"maximum":24,"type":"number"},"einspeisung_ct":{"minimum":0,"description":"Vergütung je eingespeister kWh; 0 = keine","type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"einfuehrung":{"additionalProperties":false,"description":"Hausanschluss: wo das Netzkabel eintritt — Anfang jeder Trasse","type":"object","properties":{"etage":{"minLength":1,"description":"Etage, in der das Anschlusskabel ins Gebäude kommt","type":"string"},"xy":{"description":"[x, y] in Metern, y nach oben, Ursprung frei je Etage","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"art":{"anyOf":[{"type":"string","enum":["erdkabel"]},{"type":"string","enum":["freileitung"]}]},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"erzeugung":{"additionalProperties":false,"type":"object","required":["pv"],"properties":{"wechselrichter":{"additionalProperties":false,"type":"object","properties":{"article":{"minLength":1,"type":"string"},"maker":{"minLength":1,"type":"string"},"name":{"type":"string"},"klasse":{"description":"Bauart, z. B. \"Hybrid, 3-phasig, LV 48 V\"","type":"string"},"p_ac_kW":{"type":"number"},"p_pv_kW":{"type":"number"},"ik_A":{"type":"number"},"na_schutz":{"description":"Netz- und Anlagenschutz im Gerät integriert (VDE-AR-N 4105)","type":"boolean"},"zertifikat":{"additionalProperties":false,"type":"object","properties":{"norm":{"type":"string"},"tuev":{"type":"string"},"report":{"type":"string"},"modellreihe":{"type":"string"},"firmware_zertifiziert":{"type":"string"},"firmware_werk":{"description":"Firmwarestand des gelieferten Geräts. Weicht er vom zertifizierten ab, gilt das Einheitenzertifikat nicht.","type":"string"},"status":{"type":"string"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"backup":{"additionalProperties":false,"type":"object","properties":{"typ":{"type":"string"},"umschaltzeit_ms":{"type":"number"},"passthrough_A":{"type":"number"},"ausgangsfehlerstrom_A":{"description":"Kurzschlussstrom, den das Gerät im Inselbetrieb liefert — Eingang der Abschaltbedingung ohne Netz.","type":"number"},"ueberstrom_A":{"type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"ports":{"additionalProperties":false,"type":"object","properties":{"grid":{"type":"string"},"load":{"type":"string"},"batterie":{"type":"string"},"pv":{"type":"string"}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"speicher":{"additionalProperties":false,"type":"object","properties":{"article":{"minLength":1,"type":"string"},"maker":{"minLength":1,"type":"string"},"chemie":{"description":"z. B. \"LFP 48 V LV\"","type":"string"},"u_V":{"type":"number"},"kwh":{"type":"number"},"modul_max_A":{"type":"number"},"system_max_A":{"type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"unterkonstruktion":{"description":"Montagesystem der PV-Flächen, gegen die reale Eindeckung zu prüfen","type":"string"},"pv":{"description":"PV-Flächen; leeres Array = keine Photovoltaik am Objekt","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","name","azimut_deg","neigung_deg"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"description":"z. B. \"Dach Süd\"","type":"string"},"azimut_deg":{"minimum":-180,"maximum":180,"description":"Ausrichtung: 0 = Süd, -90 = Ost, +90 = West (PVGIS-Konvention)","type":"number"},"neigung_deg":{"minimum":0,"maximum":90,"description":"Neigung gegen die Waagerechte; 0 = flach","type":"number"},"modul":{"description":"Modultyp aus dem Katalog","type":"string"},"anzahl":{"minimum":1,"type":"integer"},"kwp":{"exclusiveMinimum":0,"description":"Installierte Spitzenleistung dieser Fläche in kWp","type":"number"},"wp_modul":{"exclusiveMinimum":0,"description":"Spitzenleistung eines Moduls in Watt","type":"number"},"bifazial":{"description":"Beidseitig belegtes Modul — der Ertrag hängt zusätzlich vom Untergrund ab","type":"boolean"},"mppt":{"minimum":1,"description":"MPP-Tracker des Wechselrichters, an dem der String dieser Fläche hängt (1, 2, …). Flächen verschiedener Ausrichtung gehören an verschiedene Tracker.","type":"integer"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"pv_einspeisung":{"additionalProperties":false,"description":"Verteiler, in dem die DC-Leitungen vom Dach zuerst ankommen, bevor sie zum Wechselrichter weiterlaufen. Der Hausgraph zeichnet dort einen eigenen Einspeisepunkt. Fehlt die Angabe, führt jede PV-Fläche direkt zum Wechselrichter.","type":"object","required":["verteiler"],"properties":{"verteiler":{"minLength":1,"type":"string"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}}},"steuerung":{"additionalProperties":false,"type":"object","properties":{"netzbetreiber":{"description":"Failsafe-Ebene: Steuerbox des Netzbetreibers und was an ihr hängt (§14a EnWG).","type":"string"},"ems":{"description":"Überlagerte eigene Regelung und ihr Weg zum Gerät.","type":"string"},"p_min_14a_kW":{"exclusiveMinimum":0,"description":"Mindestleistung, auf die der Netzbetreiber nach §14a drosseln darf.","type":"number"},"wallbox_14a_A":{"exclusiveMinimum":0,"description":"Strom je Phase, auf den die Wallbox im §14a-Abruf begrenzt wird.","type":"number"},"eeg_pct":{"minimum":0,"maximum":100,"description":"Einspeisebegrenzung nach EEG §9 in Prozent der installierten Leistung.","type":"number"},"eeg_kW":{"exclusiveMinimum":0,"description":"Dieselbe Grenze in Kilowatt.","type":"number"},"netzgrenze_A":{"exclusiveMinimum":0,"description":"Höchster Strom je Phase am Netzanschluss, den die Regelung einhalten muss.","type":"number"},"insel_kW":{"exclusiveMinimum":0,"description":"Zielleistung im Inselbetrieb.","type":"number"},"messkonzept":{"type":"string"},"lastmanagement":{"additionalProperties":false,"type":"object","required":["grenze","empfehlung","stufen"],"properties":{"grenze":{"description":"Feld dieser Steuerung, das die Leiter verteidigt, z. B. \"netzgrenze_A\".","type":"string"},"empfehlung":{"description":"true = Reihenfolge und Zahlen sind unser Vorschlag, vom Betreiber frei änderbar.","type":"boolean"},"soc_min_pct":{"description":"Unter diesem Ladezustand stützt die Batterie nicht mehr.","type":"number"},"stufen":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["rang","knoten","art"],"properties":{"rang":{"type":"number"},"knoten":{"minLength":1,"type":"string"},"art":{"anyOf":[{"type":"string","enum":["dimmen"]},{"type":"string","enum":["schalten"]},{"type":"string","enum":["speicher"]}]},"aktion":{"anyOf":[{"type":"string","enum":["entladen"]},{"type":"string","enum":["pause"]},{"type":"string","enum":["laden_stop"]}]},"nur_modus":{"anyOf":[{"type":"string","enum":["heizen"]},{"type":"string","enum":["kuehlen"]}]},"hinweis":{"type":"string"}}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"planungsregeln":{"additionalProperties":false,"type":"object","required":["empfehlung","geraeteklassen"],"properties":{"empfehlung":{"description":"true = Vorschlag von uns, nicht aus einer Norm abgeleitet und frei änderbar.","type":"boolean"},"geraeteklassen":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["klasse","name","mehrphasig_moeglich","quelle"],"properties":{"klasse":{"minLength":1,"type":"string"},"name":{"type":"string"},"mehrphasig_moeglich":{"description":"Gibt es diese Geräteart auch mehrphasig? Dann lohnt die fünfte Ader schon beim ersten Mal.","type":"boolean"},"eigener_kreis":{"description":"Gehört dieser Geräteart ein eigener Stromkreis? Ohne Beleg bleibt die Regel dazu stumm: die Mindestausstattung steht in DIN 18015-2, und die liegt hier nicht vor.","type":"boolean"},"stromkreis":{"description":"Eine Gruppe von Auslässen (Steckdosen, Licht, Bad), kein einzelnes Gerät: ihre Last ist der Bemessungsstrom des Schutzorgans, nicht ein Datenblattwert.","type":"boolean"},"quelle":{"minLength":1,"description":"id aus catalog/normen.json — keine Prosa. Damit wird die Fundstelle aufgelöst, nicht getippt.","type":"string"},"hinweis":{"type":"string"}}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"lichtkonzept":{"additionalProperties":false,"type":"object","properties":{"regel":{"type":"string"},"steuerstellen":{"description":"Aderzahl der Steuerstelle und ihr Grund — Dimmer und Melder brauchen den Neutralleiter.","type":"string"},"treiber_24V":{"description":"Wo die Treiber sitzen dürfen: zugänglich und belüftet, nicht eingemauert.","type":"string"},"linien_je_zone":{"minimum":1,"type":"integer"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"verteiler":{"minItems":1,"type":"array","items":{"additionalProperties":false,"description":"One low-voltage switchgear assembly: enclosure with rails and fields, devices with their BMK, conductors between them. A distribution board whose contents have not been surveyed yet carries empty geraete/leiter and is reported as \"no data\".","type":"object","required":["id","name","knoten","geraete","leiter"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"type":"string"},"ort":{"description":"Aufstellungsort, z. B. \"Technikraum\"","type":"string"},"etage":{"minLength":1,"type":"string"},"pos":{"description":"Standort im Grundriss dieser Etage, in Metern. Anfang jeder Leitung — daraus kommen die Leitungslängen und damit die Begründung, wo der Verteiler stehen soll.","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"gehaeuse":{"additionalProperties":false,"type":"object","required":["ebenen","kopf_y_mm","te_mm","felder","gesperrt"],"properties":{"article":{"minLength":1,"type":"string"},"maker":{"minLength":1,"type":"string"},"b_mm":{"type":"number"},"h_mm":{"type":"number"},"t_mm":{"type":"number"},"kanal_tiefe_mm":{"exclusiveMinimum":0,"description":"Nutzbare Tiefe der Verdrahtungsräume (Abstand Montageebene/Hutschiene zur Berührungsschutzabdeckung). Aus dem Systemhandbuch des Gehäuses; ohne Angabe rechnet die Verlegung mit einer benannten Annahme.","type":"number"},"felder_anzahl":{"type":"number"},"reihen_anzahl":{"type":"number"},"in_A":{"type":"number"},"ip":{"type":"string"},"ik":{"type":"string"},"sk":{"type":"string"},"ebenen":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","y_mm"],"properties":{"id":{"minLength":1,"type":"string"},"y_mm":{"type":"number"},"felder":{"description":"Felder nur dieser Reihe, wenn ihr Baustein von der Gehäuseteilung abweicht — etwa ein univers-N-Baustein UD..B2 mit durchgehendem Geräteschlitz über beide Felder. Ohne Angabe gelten die Felder des Gehäuses.","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","x_mm"],"properties":{"id":{"minLength":1,"type":"string"},"x_mm":{"type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2}}}}}}},"kopf_y_mm":{"type":"number"},"te_mm":{"type":"number"},"felder":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","x_mm"],"properties":{"id":{"minLength":1,"type":"string"},"x_mm":{"type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2}}}},"bausteine":{"description":"Einbausätze des Gehäuses (univers N: UD..B1/B2, UK21A3) — Gruppe A der Stückliste; lage nennt die Reihen und Felder.","type":"array","items":{"additionalProperties":false,"type":"object","required":["article","maker","name","lage","src"],"properties":{"article":{"minLength":1,"type":"string"},"maker":{"minLength":1,"type":"string"},"name":{"type":"string"},"lage":{"type":"string"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"gesperrt":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["ebene","feld","grund"],"properties":{"ebene":{"minLength":1,"type":"string"},"feld":{"minLength":1,"type":"string"},"grund":{"type":"string"}}}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"thermik":{"additionalProperties":false,"type":"object","required":["tamb_C"],"properties":{"tamb_C":{"type":"number"},"dt_mid_K":{"type":"number"},"dt_top_K":{"type":"number"},"k":{"exclusiveMinimum":0,"type":"number"},"c":{"exclusiveMinimum":0,"type":"number"},"x":{"exclusiveMinimum":0,"type":"number"},"d":{"exclusiveMinimum":0,"type":"number"},"rdf":{"exclusiveMinimum":0,"maximum":1,"type":"number"},"grenze_W":{"type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"derating":{"type":"object","additionalProperties":{"additionalProperties":false,"type":"object","required":["in_A","iz_A"],"properties":{"in_A":{"type":"number"},"iz_A":{"type":"object","additionalProperties":{"type":"number"}},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"knoten":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","art","name","src"],"properties":{"id":{"minLength":1,"type":"string"},"art":{"minLength":1,"type":"string"},"name":{"type":"string"},"ports":{"type":"array","items":{"minLength":1,"type":"string"}},"klasse":{"minLength":1,"description":"Geräteklasse des Verbrauchers, Schlüssel in planungsregeln.geraeteklassen. Sie sagt nicht, was heute hängt, sondern was hier je hängen kann — daran hängt, wie viele Adern man legt.","type":"string"},"artikel":{"minLength":1,"description":"Artikelbezeichnung des Geräts, das an diesem Knoten hängt — dieselbe Rolle wie article beim Betriebsmittel im Verteiler. Sie ist der Schlüssel, an dem Datenblatt, Stückliste, Bestellung, Rechnung und Gewährleistung zusammenfinden.","type":"string"},"datenblatt":{"minLength":1,"description":"Pfad unterhalb data/<projekt>/datasheets/, z. B. \"keba/KeContact_P40_…_DE.pdf\".","type":"string"},"leistung_W":{"minimum":0,"description":"Betriebsleistung des Verbrauchers aus dem Datenblatt — für die Simulation des Hauses (Betrieb, Lastmanagement). Die Bemessung des Stromkreises bleibt last_A am Leiter: ein Fancoil zieht 33 W, sein Kreis ist auf 8 A ausgelegt.","type":"number"},"ziel":{"minLength":1,"description":"Nur bei art \"unterverteilung\": id des gespeisten Verteilers. Ohne dieses Feld steht die Verbindung der Verteiler nur im Klartext des Namens und ist für das Programm unsichtbar.","type":"string"},"steuerbar":{"additionalProperties":false,"description":"Ob und wie dieser Verbraucher vom Lastmanagement geführt werden darf. Ohne dieses Feld ist er Last und wird nie abgeworfen (§14a EnWG: nur steuerbare Verbrauchseinrichtungen).","type":"object","required":["art","src"],"properties":{"art":{"anyOf":[{"type":"string","enum":["dimmen"]},{"type":"string","enum":["schalten"]},{"type":"string","enum":["speicher"]}]},"stufen_A":{"description":"Nur bei \"dimmen\": Stromstufen absteigend.","type":"array","items":{"type":"number"}},"boden_A":{"description":"Kleinster zulässiger Strom, unter den nicht geregelt wird.","type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}},"steuerung":{"description":"Steuerungskonzept des Verbrauchers, z. B. Tastdimmer oder Präsenzmelder.","type":"string"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"schienen":{"description":"Sammelschienen der Kombination: PE und die N-Schienen der Gruppen.","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","art","name","src"],"properties":{"id":{"minLength":1,"type":"string"},"art":{"description":"PE-Schiene oder N-Schiene","anyOf":[{"type":"string","enum":["pe"]},{"type":"string","enum":["n"]}]},"name":{"type":"string"},"quelle":{"minLength":1,"description":"Gerät, aus dem diese Schiene gespeist wird — bei einer N-Gruppe das RCD","type":"string"},"y_mm":{"description":"Höhe über der Gehäuseunterkante","type":"number"},"x_mm":{"description":"Erstreckung in der Breite; ohne Angabe über das ganze Gehäuse","type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"betriebsarten":{"description":"Betriebsarten dieser Kombination: Normalbetrieb, Service-Bypass, Trennung, Inselbetrieb.","type":"array","items":{"additionalProperties":false,"type":"object","required":["id","name","weg"],"properties":{"id":{"minLength":1,"type":"string"},"name":{"type":"string"},"weg":{"description":"Der Strompfad dieser Betriebsart, Knoten für Knoten.","type":"string"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"geraete":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["bmk","article","maker","name","ebene","src"],"properties":{"bmk":{"minLength":1,"type":"string"},"article":{"minLength":1,"type":"string"},"maker":{"minLength":1,"type":"string"},"name":{"type":"string"},"te":{"type":"number"},"ebene":{"minLength":1,"type":"string"},"x_mm":{"type":"array","items":[{"type":"number"},{"type":"number"}],"additionalItems":false,"minItems":2,"maxItems":2},"z_mm":{"type":"number"},"h_mm":{"exclusiveMinimum":0,"description":"Bauhöhe in Millimetern. Fehlt sie, gilt die Normhöhe der Reiheneinbaugeräte nach DIN 43880 (90 mm); größere Geräte wie Leistungsschalter und Lastumschalter tragen ihr Maß aus dem Datenblatt.","type":"number"},"b_mm":{"exclusiveMinimum":0,"description":"Physische Baubreite in Millimetern aus dem Datenblatt — getrennt von den belegten Teilungseinheiten. Ein Gerät mit «12 Module» kann breiter sein als 12 × 17,5 mm (HI403R: 215 mm) und passt dann nicht in den Geräteschlitz eines 12-PLE-Feldes.","type":"number"},"tmax_C":{"type":"number"},"verlust":{"type":"object","properties":{"fix_W":{"type":"number"},"p_W":{"type":"number"},"at_A":{"type":"number"},"pole":{"type":"number"},"spule_W":{"type":"number"}}},"schutz":{"type":"object","required":["t_s"],"properties":{"char":{"anyOf":[{"type":"string","enum":["B"]},{"type":"string","enum":["C"]}]},"in_A":{"type":"number"},"ir_A":{"type":"number"},"ii_A":{"type":"number"},"t_s":{"type":"number"}}},"iz_A":{"type":"number"},"icn_kA":{"type":"number"},"icu_kA":{"type":"number"},"ics_kA":{"type":"number"},"inc_kA":{"type":"number"},"idm_kA":{"type":"number"},"icw_kA":{"type":"number"},"drehmoment_Nm":{"type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"leiter":{"type":"array","items":{"additionalProperties":false,"type":"object","required":["id","von","nach","typ","s_mm2","l_m","src"],"properties":{"id":{"minLength":1,"type":"string"},"von":{"minLength":1,"type":"string"},"nach":{"anyOf":[{"minLength":1,"type":"string"},{"type":"array","items":{"minLength":1,"type":"string"}}]},"typ":{"type":"string"},"art":{"description":"Keine Adern, sondern eine Kammschiene zwischen benachbarten Geräten einer Reihe: sie sitzt auf der Klemmenseite, mit der die Geräte gespeist werden, und wird als Bauteil gezeichnet und bestellt (article), nicht als Meterware. Ohne art ist der Leiter ein Kabel oder eine Aderleitung.","type":"string","enum":["phasenschiene"]},"article":{"minLength":1,"type":"string"},"maker":{"minLength":1,"type":"string"},"s_mm2":{"type":"number"},"s_n_mm2":{"type":"number"},"s_pe_mm2":{"type":"number"},"l_m":{"type":"number"},"last_A":{"type":"number"},"last_bypass_A":{"type":"number"},"i_A":{"type":"number"},"phasen":{"description":"Zahl der belasteten Aussenleiter. 2 gibt es wirklich — zweiphasige Kochfelder auf L1+L2+N. Die Rechnung behandelt 1 und 2 als 230-V-Kreis mit Hin- und Rückweg; ein Gerät, das zwischen zwei Aussenleitern auf 400 V ohne N liegt, ist damit NICHT beschrieben.","anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]}]},"phase":{"anyOf":[{"type":"string","enum":["L1"]},{"type":"string","enum":["L2"]},{"type":"string","enum":["L3"]}]},"phase_je_ziel":{"description":"For a conductor with several targets (nach is a list): which outer conductor feeds which target, e.g. {\"F7\":\"L1\",\"F11\":\"L2\",\"F1\":\"L3\"}. Needed for every single-pole target (1P or 1P+N) — without it the drawing cannot tell which core lands on which terminal, the phase currents load all three phases, and the check «Phase je Ziel» stays open. Keys must be targets of this conductor.","type":"object","additionalProperties":{"anyOf":[{"type":"string","enum":["L1"]},{"type":"string","enum":["L2"]},{"type":"string","enum":["L3"]}]}},"betrieb":{"anyOf":[{"type":"string","enum":["normal"]},{"type":"string","enum":["bypass"]}]},"quelle_artikel":{"minLength":1,"description":"Artikel, aus dessen Datenblatt die elektrischen Werte dieses Leiters stammen. Weicht er vom artikel des gespeisten Verbrauchers ab, wurde das Gerät getauscht und die Werte gelten nicht mehr — die Regel \"Quelle veraltet\" meldet es.","type":"string"},"richtung":{"description":"Wohin das abgehende Kabel das Gehäuse verlässt: oben (Decke, Licht) oder unten (Boden, Steckdosen).","anyOf":[{"type":"string","enum":["oben"]},{"type":"string","enum":["unten"]}]},"n_von":{"minLength":1,"description":"Wo der Neutralleiter dieses Kabels aufgelegt ist: eine Schiene aus `schienen` oder das Gerät, das ihn führt — der N-Verteilerblock, oder bei einem FI/LS dessen eigene N-Klemme. Hinter einem RCD darf es nicht die gemeinsame Schiene sein.","type":"string"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}}}}},"konstanten":{"additionalProperties":false,"type":"object","required":["rho_verlust","rho_kurzschluss","c_min","pe_intern_mm2"],"properties":{"rho_verlust":{"type":"number"},"rho_kurzschluss":{"type":"number"},"c_min":{"type":"number"},"pe_intern_mm2":{"type":"number"},"src":{"description":"Quelle jedes Werts: Dokument, Datenblatt, Messung. Ohne Quelle kein Wert.","type":"string"}}}},"title":"Objekt"}}},"paths":{"/api/v1/projects":{"get":{"tags":["projects"],"description":"List projects accessible to the authenticated user with their cover-sheet meta. Other projects are not disclosed.","security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["id","meta"],"properties":{"id":{"type":"string"},"meta":{}}}}}}}}}},"/api/v1/access":{"get":{"tags":["meta"],"description":"Current user and project roles. Never returns access keys or their hashes.","security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/anmelden":{"post":{"tags":["konten"],"description":"Sign in with e-mail and password. Returns a bearer token for all other calls, valid for 30 days from sign-in. 429 after 10 failed attempts for one address within 15 minutes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","passwort"],"properties":{"email":{"minLength":3,"maxLength":254,"type":"string"},"passwort":{"minLength":1,"maxLength":1024,"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/abmelden":{"post":{"tags":["konten"],"description":"Sign out: invalidates the bearer token sent with this request.","responses":{"200":{"description":"Default Response"}}}},"/api/v1/einladungen/pruefen":{"post":{"tags":["konten"],"description":"Look up an invitation by the token from its link (token in the body, never in the URL). Tells the invitee which project and role, and whether an account already exists for the address.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"minLength":20,"maxLength":100,"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/einladungen/einloesen":{"post":{"tags":["konten"],"description":"Redeem an invitation. New address: sets the password (min. 10 characters). Existing account: the current password is required. Returns a bearer token.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","passwort"],"properties":{"token":{"minLength":20,"maxLength":100,"type":"string"},"passwort":{"minLength":1,"maxLength":1024,"type":"string"}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/einladungen":{"post":{"tags":["konten"],"description":"Invite a person into this project by e-mail. Only the project owner (or the administrator) may invite; only the administrator may appoint an owner. Sends a single-use link valid for 7 days.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","rolle"],"properties":{"email":{"minLength":3,"maxLength":254,"type":"string"},"rolle":{"anyOf":[{"type":"string","enum":["besitzer"]},{"type":"string","enum":["editor"]},{"type":"string","enum":["viewer"]}]}}}}}},"parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}":{"get":{"tags":["projects"],"description":"Return the complete model of one switchgear project: meta, network, enclosure with rails and fields, thermal data, derating tables, devices (BMK, article, place, ratings) and conductors. Coordinates are millimetres, y up, origin at the lower left inner corner. Every value carries src — the document, datasheet or measurement it comes from.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Model of one building: its floors, its grid connection, its generation and storage, and its distribution boards. Every table of the German Projektmappe (Leiterliste, Verlustbilanz, Erwärmung, Impedanzen, Stückliste) is derived from one board of this model, never stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/def-0"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{}}}}}}}}},"put":{"tags":["projects"],"description":"Replace the whole model. Prefer PATCH for edits. Rejected with 422 SCHEMA_INVALID or 422 INVARIANT_VIOLATION (duplicate BMK or conductor number, unknown rail, conductor starting at a node that does not exist). On success the file is committed to git and connected clients re-render.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/def-0"}}}},"parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["ok","revision","warnings"],"properties":{"ok":{"type":"boolean","enum":[true]},"revision":{"description":"git short hash after the write","type":"string"},"warnings":{"description":"Non-blocking invariant violations (e.g. conductor without src, unreachable from SLS)","type":"array","items":{}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{}}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{}}}}}}}}},"patch":{"tags":["projects"],"description":"Apply an RFC 6902 JSON-Patch to the current model — the intended way to add or remove a load: e.g. [{\"op\":\"add\",\"path\":\"/geraete/-\",\"value\":{…}},{\"op\":\"add\",\"path\":\"/leiter/-\",\"value\":{…}}] adds a circuit, [{\"op\":\"replace\",\"path\":\"/thermik/tamb_C\",\"value\":25}] changes the ambient temperature. This is the intended way for an agent to propose changes. The patched model goes through the same schema + invariant checks as PUT; nothing is written unless all checks pass. Returns the new git revision and non-blocking warnings.","requestBody":{"required":true,"content":{"application/json":{"schema":{"minItems":1,"description":"RFC 6902 JSON-Patch document","type":"array","items":{"type":"object","required":["op","path"],"properties":{"op":{"anyOf":[{"type":"string","enum":["add"]},{"type":"string","enum":["remove"]},{"type":"string","enum":["replace"]},{"type":"string","enum":["move"]},{"type":"string","enum":["copy"]},{"type":"string","enum":["test"]}]},"path":{"type":"string"},"from":{"type":"string"},"value":{}}}}}},"description":"RFC 6902 JSON-Patch document"},"parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["ok","revision","warnings"],"properties":{"ok":{"type":"boolean","enum":[true]},"revision":{"description":"git short hash after the write","type":"string"},"warnings":{"description":"Non-blocking invariant violations (e.g. conductor without src, unreachable from SLS)","type":"array","items":{}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{}}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{}}}}}}}}}},"/api/v1/projects/{id}/violations":{"get":{"tags":["projects"],"description":"Invariant check of the stored model without writing. Returns warnings such as points lying outside their room.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{}}}}}}}}}},"/api/v1/interior":{"get":{"tags":["meta"],"description":"Versioned furniture catalog and deterministic placement rules. Presets are design defaults, not regulatory standards.","responses":{"200":{"description":"Default Response"}}}},"/api/v1/schema":{"get":{"tags":["meta"],"description":"JSON Schema of the Objekt model — building, floors, grid connection, generation and the distribution boards. Use it to construct valid PUT bodies or PATCH values.","responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/verteiler":{"get":{"tags":["verteiler"],"description":"List the distribution boards of the object with their place, floor and whether they have been surveyed. Only surveyed boards can be computed; the others are open points of the project.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/berechnung":{"get":{"tags":["berechnung"],"description":"Everything the model implies, in one call: currents per conductor, conductor list with voltage drop and I²R, loss balance for normal and bypass operation, rail temperatures with derating, TE occupancy per rail and field, impedances, proofs A (L–PE disconnection), B (L–N short circuit), C (breaking capacity) and D (Ik,min), and the bill of material. Use this instead of recomputing anything yourself.","parameters":[{"schema":{"type":"string"},"in":"query","name":"verteiler","required":false,"description":"Id of the distribution board to compute. Default: the first board (the main one). Call GET /verteiler for the list."},{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/auswahl":{"post":{"tags":["berechnung"],"description":"Automatically select protective devices and arrange functional groups, DIN equipment and neutral bars. Enforces known temperature/current limits and physical widths; reports unknown evidence and any required enclosure expansion. Read-only planning variant: the installed model is retained. Client routing verification and a new thermal/mounting assessment remain required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","properties":{"reserve_K":{"minimum":0,"maximum":30,"type":"number"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"query","name":"verteiler","required":false,"description":"Id of the distribution board to compute. Default: the first board (the main one). Call GET /verteiler for the list."},{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/pruefungen":{"get":{"tags":["pruefung"],"description":"Run the rule engine on the model: cable ampacity, protective device vs. cable, voltage drop, device temperature limits and derating, heat balance against the enclosure limit, spare capacity, breaking capacity, disconnection condition, SPD cable length and phase balance. Each finding names rule, severity (fehler/warnung/offen), reference, actual, required and the standard.","parameters":[{"schema":{"type":"string"},"in":"query","name":"verteiler","required":false,"description":"Id of the distribution board to compute. Default: the first board (the main one). Call GET /verteiler for the list."},{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/pruefungen/alle":{"get":{"tags":["pruefung"],"description":"Run the rule engine on every surveyed board of the object at once and return one row per board: counts of fehler/warnung/offen plus the findings. Boards not yet surveyed are listed with aufgenommen=false and no findings. The response also carries \"bedarf\": how often a conclusion could not be drawn for lack of a standard we do not hold, per standard — use it to decide which subscription actually pays for itself. Use this to see whether a rule holds across the whole object instead of calling /pruefungen once per board.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/normen/{norm}":{"get":{"tags":["pruefung"],"description":"Return the versions of a norm that were in force on a given date. The date is required: a norm has no single text, only a text per day, and answering without one would mean guessing which. Returns a list, because two versions can share an effective date — then both are returned and the caller must not pick one silently. An empty list means nothing was in force here on that day, which is an answer and not an error.","parameters":[{"schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"},"in":"query","name":"an","required":true},{"schema":{"type":"string"},"in":"path","name":"norm","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/haus":{"get":{"tags":["berechnung"],"description":"Return the whole object as one graph: every node and conductor of every board, joined at the board boundaries. The supply cable of a sub-board is stored twice in the model (once from each end); it is returned once, with both source ids in \"vereint\". \"widersprueche\" lists values that disagree between the two copies — resolve them in the model, they are not averaged here. Use this instead of calling /verteiler once per board when a question crosses boards.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/betrieb":{"post":{"tags":["berechnung"],"description":"Solve one declared situation to its steady state: which consumers are switched on, which operating mode, how much the PV delivers, how full the battery is. Returns the current in every conductor of the house, the current at the grid connection, and every action the load management took, in the order it took them. There is no time in this model — a scenario is an ordered list of situations, not a sequence of seconds. Use this when the question is \"what happens if\" across the whole object — instead of /berechnung, which reports one board at its declared load and knows nothing of switch state, sun, battery or load management. Modes the solver cannot determine (\"insel\", \"wallbox\") and consumer ids the object does not have are rejected with 422 SCHEMA_INVALID rather than answered with a number.","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["betriebsart","wp_modus","pv_kW","soc_pct","ein"],"properties":{"betriebsart":{"description":"id aus verteiler[uv1].betriebsarten, z. B. \"normal\".","type":"string"},"wp_modus":{"anyOf":[{"type":"string","enum":["heizen"]},{"type":"string","enum":["kuehlen"]},{"type":"string","enum":["aus"]}]},"pv_kW":{"minimum":0,"type":"number"},"pv_je_flaeche":{"description":"PV power per area in kW (e.g. one PVGIS hour). When given, its sum is the PV power and pv_kW is ignored.","type":"object","additionalProperties":{"minimum":0,"type":"number"}},"soc_pct":{"minimum":0,"maximum":100,"type":"number"},"speicher":{"description":"Battery behaviour: \"lastzuerst\" (default; Deye manual §5.7: PV feeds the load, surplus charges, deficit discharges above the minimum SOC, then grid) or \"aus\" (battery idle, for comparison).","anyOf":[{"type":"string","enum":["lastzuerst"]},{"type":"string","enum":["aus"]}]},"ein":{"type":"array","items":{"description":"Knoten-id im Haus-Graphen, z. B. \"uv-eg/V-EF1\".","type":"string"}}}}}}},"parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/journal":{"get":{"tags":["journal"],"description":"The project journal: one stream of entries in time order — what the watchdog agent observed, which Punkte it proposed (stand \"vorgeschlagen\", never decided by the agent), what the owner wrote in between. Read it to see the agents at work; write with POST to add a human line.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}},"post":{"tags":["journal"],"description":"Append a human entry to the journal (the owner writing at the cursor). Requires the access key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["text"],"properties":{"text":{"minLength":1,"maxLength":4000,"type":"string"},"bezug":{"type":"object","properties":{"punkt":{"type":"integer"}}}}}}}},"parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/chat":{"post":{"tags":["journal"],"description":"Ask the project concierge a question. It runs as a separate Claude Code process on the operator's own subscription (no API key), sees the model, the rules, the datasheets, the uploaded documents and the web, and answers in the language of the question. It never changes the model. The call returns 202 at once: the question is in the journal, the answer follows there when the run ends (up to 20 minutes; GET /journal says konzierge_laeuft). One run per project at a time (409 otherwise). Capped per day. Requires the access key (editor).","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["frage"],"properties":{"frage":{"minLength":3,"maxLength":20000,"type":"string"},"model":{"maxLength":60,"description":"z. B. \"opus\" für eine schwere Frage; sonst die Vorgabe.","type":"string"}}}}}},"parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/waechter":{"post":{"tags":["journal"],"description":"Run the watchdog now: all checks on all boards, diff against the remembered state, propose a Punkt for every new error/warning via the configured LLM (none configured → observations only). Returns what moved. The same run happens automatically after every model write.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/ertrag":{"get":{"tags":["abgeleitet"],"description":"Photovoltaic yield of the object, hour by hour, from PVGIS (JRC) for the coordinates and the module planes stored in the model. Returns the yearly and monthly kWh per plane and in total, plus the ambient temperature series PVGIS delivers with it. The raw PVGIS answer is cached in the project folder; it is fetched again only when place, tilt, azimuth, peak power or losses change. Requires gebaeude.lat and gebaeude.lon — without them nothing is guessed. With ?reihen=1 each plane also carries its hourly series (zeit[], stunden[] in kW) — what the house sheet reads to set the sun of a chosen hour.","parameters":[{"schema":{"type":"string"},"in":"query","name":"reihen","required":false},{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/waerme":{"get":{"tags":["abgeleitet"],"description":"Heating demand of the building, hour by hour, against the outdoor temperature PVGIS delivers with the yield for this location. The model carries no U-values, window areas or thermal bridges, so this is NOT a heat load to DIN EN 12831: it is a band between two named building standards (GEG 2020 reference values and the EnEV 2002 level), each marked as an assumption that has not been verified on the object. Returns the loss coefficient in W/K, yearly heat and electricity, the specific demand in kWh/(m²·a) and a verdict against the efficiency classes.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/szenario":{"get":{"description":"What actually runs in a given hour, and why. The model decides: outdoor temperature (PVGIS) → heat demand → heat pump, hot water, immersion heaters, wallbox, household base load → PV, battery, grid. Every consumer carries a sentence that justifies its state. Call this when the user asks \"why is the heat pump off today\", \"will the sun charge the battery\", or wants the worst hours of the year rather than an annual average. Parameters (heating limit 15 °C, indoor 20 °C, bivalence −5 °C, wallbox scenario, household profile) are the owner's decision of 2026-09-22 and are returned with the answer. COP between the datasheet points is interpolated and marked as such.","parameters":[{"schema":{"type":"string"},"in":"query","name":"tag","required":false,"description":"MM-TT, z. B. \"09-22\". Ohne Angabe: heute."},{"schema":{"minimum":0,"maximum":23,"type":"integer"},"in":"query","name":"stunde","required":false},{"schema":{"minimum":0,"maximum":100,"type":"number"},"in":"query","name":"soc_pct","required":false},{"schema":{"type":"boolean"},"in":"query","name":"jahr","required":false,"description":"Zusätzlich die Extremstunden des Jahres."},{"schema":{"anyOf":[{"type":"string","enum":["archiv"]},{"type":"string","enum":["typjahr"]}]},"in":"query","name":"wetter","required":false,"description":"archiv = wirkliches Wetter des Jahres (ERA5), typjahr = PVGIS-Mittel. Vorgabe: archiv."},{"schema":{"minimum":1950,"maximum":2100,"type":"integer"},"in":"query","name":"jahr_wetter","required":false},{"schema":{"type":"boolean"},"in":"query","name":"nachtladung","required":false,"description":"Nachts aus dem Netz laden, soweit der Tarif es trägt und der Tag danach es braucht. Vorgabe: ja."},{"schema":{"type":"boolean"},"in":"query","name":"bypass","required":false,"description":"HI403R in Stellung I: Wechselrichter, PV und Batterie herausgeschaltet, das Haus unmittelbar am Netz."},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/dokumente":{"get":{"tags":["belege"],"description":"List the evidence stored with this project — datasheets, planning packages, energy certificates, bills. Each entry carries the SHA-256 of the file as it is on disk right now, so a value that cites a document can be checked against the document it was read from.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["name","groesse","sha256","typ","aufgenommen_am"],"properties":{"name":{"type":"string"},"groesse":{"type":"number"},"sha256":{"type":"string"},"typ":{"type":"string"},"aufgenommen_am":{"type":"string"}}}}}}}}},"post":{"tags":["belege"],"description":"Store a document with the project. The body carries the file name and its bytes as base64 — no multipart, so an agent can upload with a plain JSON request. Accepted: PDF, PNG, JPEG, WEBP, TXT, Markdown, CSV, up to 64 MB. Returns name, size, SHA-256 and type; cite that SHA-256 in the `src` of any value read from this document.","requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"type":"object","required":["name","inhalt_base64"],"properties":{"name":{"description":"File name. Any path is stripped; only the base name is kept.","type":"string"},"inhalt_base64":{"description":"The file content, base64 encoded.","type":"string"}}}}}},"parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["name","groesse","sha256","typ","aufgenommen_am"],"properties":{"name":{"type":"string"},"groesse":{"type":"number"},"sha256":{"type":"string"},"typ":{"type":"string"},"aufgenommen_am":{"type":"string"}}}}}}}}},"/api/v1/projects/{id}/dokumente/{name}":{"get":{"tags":["belege"],"description":"Fetch one stored document. The name is cleaned the same way as on upload, so it can never point outside the project folder.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"name","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/dokumente/{name}/auslesen":{"get":{"tags":["belege"],"description":"Read values out of a stored PDF: SCOP and COP, power in kW and W, peak power in kWp, capacity in kWh, voltage, current, U-values, annual consumption, efficiency, IP rating and article numbers. Every find carries the page it stands on and the sentence it stands in, because a value without its evidence is not usable in this project. This route writes NOTHING into the model: a value enters the model only when a person takes it over with a PATCH, citing document, SHA-256 and page in `src`. A scanned sheet has no text layer; then `warnung` says so instead of pretending the sheet is empty.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"name","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/status":{"get":{"tags":["status"],"description":"Return the project status sheet: release matrix (procurement, manufacturing, assembly, connection, commissioning), the numbered open points with who is responsible and what each one blocks, the register of proofs (K-1…K-15) and the load-bearing statements with their evidence status. Empty if the project has no status file.","parameters":[{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/verlegung":{"get":{"tags":["berechnung"],"description":"Wiring routes of one distribution board: the wiring ducts derived from the enclosure (spaces between rows and beside fields), the route of every conductor through duct segments with computed length, and the fill level per segment. Use this to check whether the wiring fits (fill ≤ 70 %) and to get production wire lengths; this is the panel-building view (EPLAN-style routing list), not a drawing of individual cores.","parameters":[{"schema":{"type":"string"},"in":"query","name":"verteiler","required":false,"description":"Id of the distribution board to compute. Default: the first board (the main one). Call GET /verteiler for the list."},{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/mappe":{"get":{"tags":["mappe"],"description":"List the generated documents of the German Projektmappe for this project (Markdown) plus the assembly plan (SVG).","parameters":[{"schema":{"type":"string"},"in":"query","name":"verteiler","required":false,"description":"Id of the distribution board to compute. Default: the first board (the main one). Call GET /verteiler for the list."},{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}},"/api/v1/projects/{id}/mappe/{doc}":{"get":{"tags":["mappe"],"description":"Return one generated document: Markdown (text/markdown) or the assembly plan as SVG (image/svg+xml).","parameters":[{"schema":{"type":"string"},"in":"query","name":"verteiler","required":false,"description":"Id of the distribution board to compute. Default: the first board (the main one). Call GET /verteiler for the list."},{"schema":{"pattern":"^[a-z0-9][a-z0-9-]*$","type":"string"},"in":"path","name":"id","required":true},{"schema":{"pattern":"^[0-9a-z-]+\\.(md|svg)$","type":"string"},"in":"path","name":"doc","required":true}],"security":[{"bearer":[]}],"responses":{"200":{"description":"Default Response"}}}}}}