forked from jappel/leistungsbilanz-ts
Keep the earlier Dynamo/API considerations as historical reference only. Further Revit exchange will use CSV via the Linear plugin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1152 lines
27 KiB
Markdown
1152 lines
27 KiB
Markdown
# Revit-/Dynamo-Anbindung an die Leistungsbilanz
|
||
|
||
> **Archiviert (September 2026), keine aktuelle Implementierungsanweisung.**
|
||
> Die direkte Revit-Anbindung über Dynamo/Python, Revit-API und JSON wird nicht
|
||
> weiterverfolgt. Die weitere Revit-Arbeit ist zurückgestellt und erfolgt, wenn
|
||
> sie wieder aufgenommen wird, über den CSV-Export/-Import des Linear-Plugins
|
||
> in Revit. Siehe
|
||
> [Revit-CSV-Anforderungen](../spec/revit-csv-integration-requirements.md).
|
||
> Die zugehörigen Dynamo-Diagnoseskripte sind über den Git-Tag
|
||
> `archive/dynamo-vorueberlegungen` erreichbar.
|
||
|
||
## Zweck dieses Dokuments
|
||
|
||
Dieses Dokument beschreibt den aktuellen Stand und die gewünschte Zielrichtung für die Anbindung von Revit an die Leistungsbilanz-App.
|
||
|
||
Es soll als Arbeitsgrundlage für Codex dienen. Codex soll **zuerst die bestehende Architektur des Repositories analysieren** und danach konkrete Vorschläge für:
|
||
|
||
1. die API-Struktur der Leistungsbilanz,
|
||
2. das Austauschformat zwischen Revit und Leistungsbilanz,
|
||
3. die benötigten Dynamo-/Python-Skripte,
|
||
4. die Synchronisationslogik Revit → Leistungsbilanz,
|
||
5. die spätere Rückrichtung Leistungsbilanz → Revit
|
||
|
||
erarbeiten.
|
||
|
||
Die nachfolgend genannten Klassennamen, Endpoints und DTOs sind **Vorschläge und keine zwingenden Vorgaben**. Sie sollen an die tatsächlich vorhandene Architektur angepasst werden.
|
||
|
||
---
|
||
|
||
# 1. Ausgangssituation
|
||
|
||
Die Leistungsbilanz-App soll Daten aus Revit übernehmen können.
|
||
|
||
Ursprünglich war dafür ein CSV-basierter Import vorgesehen, weil Revit-Bauteillisten nativ als CSV exportiert werden können.
|
||
|
||
Inzwischen ist klar, dass Dynamo mit Python genutzt werden kann und damit ein direkter Zugriff auf die Revit API möglich ist.
|
||
|
||
Dadurch ist eine wesentlich sauberere direkte Integration möglich.
|
||
|
||
Die CSV-Schnittstelle soll deshalb **nicht zwingend entfallen**, aber künftig eher als:
|
||
|
||
- manueller Importweg,
|
||
- Fallback,
|
||
- allgemeine Austauschmöglichkeit,
|
||
- Debug-/Testformat
|
||
|
||
verstanden werden.
|
||
|
||
Die primäre Revit-Integration soll perspektivisch über eine **versionierte API mit JSON als Austauschformat** erfolgen.
|
||
|
||
---
|
||
|
||
# 2. Aktueller Dynamo-Stand
|
||
|
||
Ein erster Dynamo-Python-Test funktioniert bereits.
|
||
|
||
Aktuell werden über die Revit API alle Exemplare der Kategorie:
|
||
|
||
```text
|
||
BuiltInCategory.OST_ElectricalFixtures
|
||
```
|
||
|
||
also Revit **Elektroinstallationen / Electrical Fixtures** gesammelt.
|
||
|
||
Für den aktuellen Entwicklungsstand soll bewusst zunächst **nur diese Kategorie** betrachtet werden.
|
||
|
||
Andere Kategorien können später ergänzt werden.
|
||
|
||
---
|
||
|
||
# 3. Bereits erfolgreich aus Revit gelesene Daten
|
||
|
||
Der aktuelle Python-Ansatz kann bereits folgende Daten ausgeben:
|
||
|
||
```text
|
||
ElementId
|
||
UniqueId
|
||
Familie
|
||
Typ
|
||
MEP_Raumnummer
|
||
MEP_Raumname
|
||
IFC_GUID
|
||
```
|
||
|
||
Die Zuordnung zum MEP-Raum erfolgt über den zum FamilyInstance gehörenden MEP Space.
|
||
|
||
Der aktuelle Test zeigt, dass das grundsätzliche Auslesen über Dynamo/Python funktioniert.
|
||
|
||
---
|
||
|
||
# 4. Relevante Identitäten
|
||
|
||
Für die Kopplung zwischen Revit und Leistungsbilanz sollen mehrere Identifikatoren berücksichtigt werden.
|
||
|
||
## 4.1 Revit UniqueId
|
||
|
||
Die `UniqueId` soll die primäre Revit-seitige Elementidentität darstellen.
|
||
|
||
Sie sollte für die dauerhafte Zuordnung eines Revit-Elements verwendet werden.
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
revitUniqueId = "0a52cc55-..."
|
||
```
|
||
|
||
---
|
||
|
||
## 4.2 ElementId
|
||
|
||
Die Revit `ElementId` soll ebenfalls übertragen werden.
|
||
|
||
Sie ist nützlich für:
|
||
|
||
- Debugging,
|
||
- Fehlersuche,
|
||
- Anzeige für den Anwender,
|
||
- direkte Suche eines Elements in Revit.
|
||
|
||
Sie soll aber **nicht als alleiniger persistenter Schlüssel** zwischen den Systemen verwendet werden.
|
||
|
||
---
|
||
|
||
## 4.3 IFC GUID
|
||
|
||
Die IFC GUID soll ebenfalls mitgeführt werden, sofern sie im Revit-Modell vorhanden ist.
|
||
|
||
Damit entsteht perspektivisch eine Verbindung:
|
||
|
||
```text
|
||
Revit
|
||
↕ UniqueId
|
||
Leistungsbilanz
|
||
↕ IFC GUID
|
||
IFC
|
||
```
|
||
|
||
Die IFC GUID ist damit insbesondere für spätere IFC-basierte Integrationen relevant.
|
||
|
||
---
|
||
|
||
# 5. Zusätzlich benötigte Modellidentität
|
||
|
||
Die `UniqueId` identifiziert ein Element innerhalb eines Revit-Modells.
|
||
|
||
Deshalb benötigt die Leistungsbilanz zusätzlich eine stabile Identität des Revit-Modells.
|
||
|
||
Vorgeschlagener Schlüssel:
|
||
|
||
```text
|
||
revitModelId
|
||
```
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
550e8400-e29b-41d4-a716-446655440000
|
||
```
|
||
|
||
Diese ID darf nicht ausschließlich aus folgenden Informationen erzeugt werden:
|
||
|
||
```text
|
||
Dateiname
|
||
Dateipfad
|
||
lokaler Speicherort
|
||
```
|
||
|
||
da sich diese ändern können.
|
||
|
||
Mögliche Speicherorte in Revit:
|
||
|
||
### Variante A – Projektparameter
|
||
|
||
Zum Beispiel:
|
||
|
||
```text
|
||
LB_ProjectId
|
||
LB_ModelId
|
||
```
|
||
|
||
Vorteile:
|
||
|
||
- einfach umzusetzen,
|
||
- sichtbar,
|
||
- leicht zu debuggen,
|
||
- direkt über Dynamo lesbar.
|
||
|
||
### Variante B – Revit Extensible Storage
|
||
|
||
Langfristig eleganter, weil integrationsspezifische Metadaten unsichtbar im Modell gespeichert werden können.
|
||
|
||
Beispielsweise:
|
||
|
||
```text
|
||
LeistungsbilanzConnector
|
||
{
|
||
modelId
|
||
projectId
|
||
lastSync
|
||
}
|
||
```
|
||
|
||
Für einen ersten Prototyp ist ein Projektparameter wahrscheinlich ausreichend.
|
||
|
||
---
|
||
|
||
# 6. Grundprinzip der Zielarchitektur
|
||
|
||
Die Revit-Schnittstelle soll nicht direkt an interne Datenbanktabellen gekoppelt werden.
|
||
|
||
Empfohlen wird:
|
||
|
||
```text
|
||
┌──────────────────────────── REVIT ────────────────────────────┐
|
||
│ │
|
||
│ Revit API │
|
||
│ ↓ │
|
||
│ Dynamo + Python │
|
||
│ ↓ │
|
||
│ Revit-Adapter │
|
||
│ ↓ │
|
||
│ definiertes Austauschmodell │
|
||
│ ↓ │
|
||
│ JSON │
|
||
│ │
|
||
└───────────────────────┬───────────────────────────────────────┘
|
||
│
|
||
│ HTTP / REST
|
||
▼
|
||
┌──────────────────── LEISTUNGSBILANZ ──────────────────────────┐
|
||
│ │
|
||
│ Revit Integration API │
|
||
│ ↓ │
|
||
│ Import-/Sync-Service │
|
||
│ ↓ │
|
||
│ persistierte Revit-Referenz │
|
||
│ ↓ │
|
||
│ Zuordnung zu DeviceRow / Circuit / bestehendem Datenmodell │
|
||
│ │
|
||
└───────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
Wichtig:
|
||
|
||
> JSON ist das Austauschformat. HTTP ist nur der Transportweg.
|
||
|
||
Dasselbe Datenmodell soll deshalb bei Bedarf auch als JSON-Datei gespeichert und eingelesen werden können.
|
||
|
||
---
|
||
|
||
# 7. Austauschmodell / DTO
|
||
|
||
Es soll ein klar definiertes und versioniertes Austauschformat geben.
|
||
|
||
Beispiel:
|
||
|
||
```json
|
||
{
|
||
"schemaVersion": 1,
|
||
"source": "revit",
|
||
"model": {
|
||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"name": "26009_F60_ELT"
|
||
},
|
||
"elements": [
|
||
{
|
||
"uniqueId": "f4d3c...",
|
||
"elementId": 471123,
|
||
"ifcGuid": "2X9...",
|
||
"category": "Electrical Fixtures",
|
||
"family": "Steckdose JUNG LS990",
|
||
"type": "Schuko 1-fach",
|
||
"space": {
|
||
"number": "1.03",
|
||
"name": "Schlafen"
|
||
},
|
||
"parameters": {
|
||
"power": 250,
|
||
"cosPhi": 0.95
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Das tatsächliche Schema soll durch Codex anhand des bestehenden Datenmodells der Leistungsbilanz konkretisiert werden.
|
||
|
||
---
|
||
|
||
# 8. Trennung zwischen Revit-Objekt und Leistungsbilanz-Objekt
|
||
|
||
Ein Revit-Element soll **nicht direkt mit einer DeviceRow gleichgesetzt werden**.
|
||
|
||
Das ist wichtig, weil:
|
||
|
||
- Revit den geplanten Modellstand enthält,
|
||
- Nutzer Werte in der Leistungsbilanz überschreiben können,
|
||
- ein importiertes Revit-Element erst vom Nutzer einem bestehenden oder neuen Stromkreis bzw. einer DeviceRow zugeordnet werden kann,
|
||
- ein erneuter Sync keine bewussten Benutzeränderungen überschreiben darf.
|
||
|
||
Konzeptionell sollte deshalb eine separate Revit-Referenz existieren.
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
RevitElement
|
||
│
|
||
│ verknüpft mit
|
||
▼
|
||
LinkedDevice / Zuordnung
|
||
│
|
||
▼
|
||
DeviceRow
|
||
│
|
||
▼
|
||
Circuit
|
||
```
|
||
|
||
Die tatsächliche Umsetzung muss Codex mit der vorhandenen Architektur abgleichen.
|
||
|
||
Mögliche Eigenschaften einer persistierten Revit-Referenz:
|
||
|
||
```text
|
||
id
|
||
revitModelId
|
||
revitUniqueId
|
||
revitElementId
|
||
ifcGuid
|
||
|
||
category
|
||
family
|
||
type
|
||
|
||
spaceNumber
|
||
spaceName
|
||
|
||
rawData
|
||
lastSeenAt
|
||
lastSyncAt
|
||
```
|
||
|
||
Die Bezeichnung `RevitElement` ist nur ein Vorschlag.
|
||
|
||
Wenn es im aktuellen Datenmodell bereits eine passende Entität gibt, soll diese verwendet oder erweitert werden.
|
||
|
||
---
|
||
|
||
# 9. Revit → Leistungsbilanz
|
||
|
||
Der erste zu implementierende Sync soll in diese Richtung erfolgen.
|
||
|
||
```text
|
||
Revit
|
||
↓
|
||
Dynamo
|
||
↓
|
||
Python / Revit API
|
||
↓
|
||
JSON Payload
|
||
↓
|
||
HTTP POST
|
||
↓
|
||
Leistungsbilanz API
|
||
↓
|
||
Sync-Service
|
||
```
|
||
|
||
## Vorgeschlagenes Verhalten
|
||
|
||
Der Benutzer startet in Dynamo bewusst einen Export bzw. Sync.
|
||
|
||
Das Python-Skript:
|
||
|
||
1. liest alle relevanten `OST_ElectricalFixtures`,
|
||
2. liest die definierten Revit-Daten,
|
||
3. erzeugt das versionierte JSON,
|
||
4. sendet es an die Leistungsbilanz,
|
||
5. wertet die HTTP-Antwort aus,
|
||
6. zeigt dem Benutzer das Ergebnis in Dynamo an.
|
||
|
||
---
|
||
|
||
# 10. Snapshot-Sync statt Delta-Sync
|
||
|
||
Für den ersten Stand soll **kein komplexer Delta-Sync** gebaut werden.
|
||
|
||
Stattdessen soll Revit bei jedem Sync einen vollständigen Snapshot aller aktuell relevanten Elektroinstallationen liefern.
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
vorher aktueller Snapshot
|
||
------------------------------------------------
|
||
Element A vorhanden Element A vorhanden
|
||
Element B vorhanden Element B vorhanden
|
||
Element C vorhanden Element C fehlt
|
||
Element D neu
|
||
```
|
||
|
||
Die Leistungsbilanz kann daraus ableiten:
|
||
|
||
```text
|
||
A → unchanged oder updated
|
||
B → unchanged oder updated
|
||
C → missing / deleted / not seen
|
||
D → created
|
||
```
|
||
|
||
Das ist für zunächst einige hundert oder tausend Elemente ausreichend und deutlich robuster.
|
||
|
||
---
|
||
|
||
# 11. Upsert-Verhalten
|
||
|
||
Auf Leistungsbilanzseite soll ein Revit-Element anhand eines stabilen Schlüssels identifiziert werden.
|
||
|
||
Vorgeschlagen:
|
||
|
||
```text
|
||
(revitModelId, revitUniqueId)
|
||
```
|
||
|
||
Beim Empfang eines Snapshots:
|
||
|
||
```text
|
||
Element bereits vorhanden?
|
||
│
|
||
├─ Nein
|
||
│ ↓
|
||
│ Create
|
||
│
|
||
└─ Ja
|
||
↓
|
||
Update
|
||
```
|
||
|
||
Die Revit-Referenz soll dabei aktualisiert werden.
|
||
|
||
Benutzerseitig überschriebene Werte einer DeviceRow dürfen dadurch jedoch nicht ungeprüft überschrieben werden.
|
||
|
||
---
|
||
|
||
# 12. Mögliche API-Struktur
|
||
|
||
Nicht zwingend exakt so umsetzen.
|
||
|
||
Codex soll prüfen, wie die aktuelle API strukturiert ist.
|
||
|
||
Mögliche Endpoints:
|
||
|
||
```http
|
||
POST /api/integrations/revit/v1/models/{modelId}/sync
|
||
```
|
||
|
||
Alternativ logisch getrennt:
|
||
|
||
```http
|
||
POST /api/integrations/revit/v1/models/{modelId}/elements
|
||
GET /api/integrations/revit/v1/models/{modelId}/writeback
|
||
```
|
||
|
||
Beispielantwort auf einen Revit-Sync:
|
||
|
||
```json
|
||
{
|
||
"syncId": "sync-9384",
|
||
"received": 483,
|
||
"created": 17,
|
||
"updated": 45,
|
||
"unchanged": 421,
|
||
"missing": 3
|
||
}
|
||
```
|
||
|
||
Die konkrete Antwortstruktur soll so gewählt werden, dass Dynamo dem Nutzer eine verständliche Zusammenfassung anzeigen kann.
|
||
|
||
---
|
||
|
||
# 13. Leistungsbilanz → Revit
|
||
|
||
Die Rückrichtung soll später ebenfalls unterstützt werden.
|
||
|
||
Sie soll jedoch zunächst **logisch vom Revit-Import getrennt** werden.
|
||
|
||
Also:
|
||
|
||
```text
|
||
PUSH
|
||
|
||
Revit
|
||
↓
|
||
Leistungsbilanz
|
||
```
|
||
|
||
und:
|
||
|
||
```text
|
||
PULL / WRITEBACK
|
||
|
||
Leistungsbilanz
|
||
↓
|
||
Revit
|
||
```
|
||
|
||
Der Benutzer soll bewusst entscheiden können, wann Daten nach Revit zurückgeschrieben werden.
|
||
|
||
Zum Beispiel:
|
||
|
||
```text
|
||
[ Revit-Daten importieren ]
|
||
|
||
[ Änderungen nach Revit schreiben ]
|
||
```
|
||
|
||
---
|
||
|
||
# 14. Writeback nicht generisch ausführen
|
||
|
||
Die Leistungsbilanz soll nicht beliebige Parameter-Namen an Revit schicken, die Dynamo anschließend blind beschreibt.
|
||
|
||
Stattdessen soll es ein definiertes Writeback-Schema geben.
|
||
|
||
Beispiel:
|
||
|
||
```json
|
||
{
|
||
"updates": [
|
||
{
|
||
"uniqueId": "abcdef...",
|
||
"values": {
|
||
"circuitNumber": "UV01-2F17",
|
||
"panel": "UV01",
|
||
"connectedLoad": 250
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Der Revit-Adapter besitzt anschließend eine feste Allowlist bzw. ein Mapping:
|
||
|
||
```text
|
||
circuitNumber
|
||
↓
|
||
LB_Stromkreisnummer
|
||
|
||
panel
|
||
↓
|
||
LB_Verteiler
|
||
|
||
connectedLoad
|
||
↓
|
||
LB_Anschlussleistung
|
||
```
|
||
|
||
Damit ist kontrolliert, welche Revit-Parameter durch die Leistungsbilanz beschrieben werden dürfen.
|
||
|
||
---
|
||
|
||
# 15. Field Ownership / Datenhoheit
|
||
|
||
Für bidirektionale Synchronisation muss definiert sein, welches System für welches Feld führend ist.
|
||
|
||
Beispiel:
|
||
|
||
| Information | Führendes System |
|
||
|---|---|
|
||
| Revit UniqueId | Revit |
|
||
| Revit ElementId | Revit |
|
||
| IFC GUID | Revit |
|
||
| Familie | Revit |
|
||
| Typ | Revit |
|
||
| MEP Raum | Revit |
|
||
| MEP Raumnummer | Revit |
|
||
| Zuordnung zu DeviceRow | Leistungsbilanz |
|
||
| Zuordnung zu Circuit | Leistungsbilanz |
|
||
| manuell überschriebene Leistung | Leistungsbilanz |
|
||
| Sicherung | Leistungsbilanz |
|
||
| Leitung | Leistungsbilanz |
|
||
| Stromkreisnummer | Leistungsbilanz, ggf. Writeback |
|
||
| Verteilerzuordnung | Leistungsbilanz, ggf. Writeback |
|
||
|
||
Diese Tabelle muss anhand des bestehenden Datenmodells vervollständigt werden.
|
||
|
||
Ziel ist, Konflikte wie diesen zu vermeiden:
|
||
|
||
```text
|
||
Revit:
|
||
Leistung = 500 W
|
||
|
||
Leistungsbilanz:
|
||
Nutzer überschreibt auf 750 W
|
||
|
||
nächster Revit-Sync:
|
||
Revit liefert wieder 500 W
|
||
```
|
||
|
||
Der bewusste Benutzerwert darf nicht kommentarlos verloren gehen.
|
||
|
||
---
|
||
|
||
# 16. Rohdaten und normalisierte Daten
|
||
|
||
Es sollte geprüft werden, ob zusätzlich zu den normalisierten Daten ein Teil des ursprünglichen Revit-Payloads gespeichert werden sollte.
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
rawData / rawPayload
|
||
```
|
||
|
||
Vorteile:
|
||
|
||
- Debugging,
|
||
- spätere Erweiterung ohne sofortigen Revit-Neuexport,
|
||
- Nachvollziehbarkeit,
|
||
- Erkennung neuer Parameter.
|
||
|
||
Dabei soll aber vermieden werden, die eigentliche Business-Logik auf unstrukturiertem JSON aufzubauen.
|
||
|
||
---
|
||
|
||
# 17. CSV und JSON-Datei weiterhin unterstützen
|
||
|
||
Auch bei einer direkten API-Anbindung sollen Datei-basierte Wege sinnvoll bleiben.
|
||
|
||
Mögliche Architektur:
|
||
|
||
```text
|
||
┌─────────────────────┐
|
||
│ Leistungsbilanz │
|
||
│ RevitSyncService │
|
||
└─────────┬───────────┘
|
||
│
|
||
┌─────────────┴─────────────┐
|
||
│ │
|
||
REST Datei
|
||
│ │
|
||
▼ ▼
|
||
Dynamo Python JSON / CSV
|
||
│
|
||
▼
|
||
Revit
|
||
```
|
||
|
||
Der gleiche interne Import-Service sollte möglichst sowohl:
|
||
|
||
```text
|
||
HTTP JSON
|
||
```
|
||
|
||
als auch:
|
||
|
||
```text
|
||
JSON-Datei
|
||
```
|
||
|
||
verarbeiten können.
|
||
|
||
CSV kann als separates allgemeines Importformat bestehen bleiben.
|
||
|
||
---
|
||
|
||
# 18. Kein direkter Datenbankzugriff aus Dynamo
|
||
|
||
Dynamo soll nicht direkt auf SQLite, PostgreSQL oder andere Datenbanken der Leistungsbilanz zugreifen.
|
||
|
||
Nicht empfohlen:
|
||
|
||
```text
|
||
Dynamo
|
||
↓
|
||
direkte SQL-Verbindung
|
||
↓
|
||
DB
|
||
```
|
||
|
||
Empfohlen:
|
||
|
||
```text
|
||
Dynamo
|
||
↓
|
||
API
|
||
↓
|
||
Business Logic
|
||
↓
|
||
ORM
|
||
↓
|
||
DB
|
||
```
|
||
|
||
Dadurch bleibt der Revit-Connector unabhängig von:
|
||
|
||
- Tabellenstruktur,
|
||
- ORM,
|
||
- Migrationen,
|
||
- internen Relationen,
|
||
- späteren Änderungen des Backends.
|
||
|
||
---
|
||
|
||
# 19. Zunächst kein WebSocket / Echtzeit-Sync
|
||
|
||
Für den aktuellen Anwendungsfall ist kein permanenter Echtzeitkanal erforderlich.
|
||
|
||
Nicht notwendig:
|
||
|
||
```text
|
||
Leistungsbilanz wird geändert
|
||
↓
|
||
sofort automatische Änderung in Revit
|
||
```
|
||
|
||
Stattdessen soll zunächst mit expliziten Sync-Aktionen gearbeitet werden.
|
||
|
||
Das ist auch im Hinblick auf Revit sinnvoll, da Änderungen über die Revit API kontrolliert und innerhalb gültiger Revit-Transactions vorgenommen werden müssen.
|
||
|
||
---
|
||
|
||
# 20. Fehlerbehandlung
|
||
|
||
Die Integration muss mit Teilfehlern umgehen können.
|
||
|
||
Beispiele:
|
||
|
||
- ein Element besitzt keinen MEP Space,
|
||
- IFC GUID fehlt,
|
||
- ein erwarteter Parameter fehlt,
|
||
- ein Revit-Parameter ist schreibgeschützt,
|
||
- HTTP-Verbindung schlägt fehl,
|
||
- API antwortet mit Validierungsfehler,
|
||
- Element wurde zwischen Abfrage und Writeback gelöscht,
|
||
- Revit-Modell ist noch nicht mit einem Leistungsbilanz-Projekt verknüpft.
|
||
|
||
Das Dynamo-Skript soll möglichst nicht beim ersten fehlerhaften Element komplett abbrechen.
|
||
|
||
Stattdessen sollte die Antwort z. B. unterscheiden:
|
||
|
||
```text
|
||
success
|
||
warnings
|
||
errors
|
||
```
|
||
|
||
und am Ende eine Zusammenfassung ausgeben.
|
||
|
||
---
|
||
|
||
# 21. Authentifizierung
|
||
|
||
Codex soll prüfen, welche Authentifizierung die aktuelle Leistungsbilanz-App bereits verwendet.
|
||
|
||
Der Dynamo-Connector soll keine unnötige zweite Authentifizierungsarchitektur einführen.
|
||
|
||
Mögliche Varianten:
|
||
|
||
- API Token,
|
||
- projektbezogenes Integration Token,
|
||
- bestehender Login-Mechanismus,
|
||
- kurzfristige Connector-Tokens.
|
||
|
||
Secrets sollen nicht fest im Dynamo-Python-Code hinterlegt werden.
|
||
|
||
---
|
||
|
||
# 22. Versionierung
|
||
|
||
Das JSON-Schema und die API sollen versioniert sein.
|
||
|
||
Beispielsweise:
|
||
|
||
```text
|
||
schemaVersion = 1
|
||
```
|
||
|
||
und/oder:
|
||
|
||
```text
|
||
/api/integrations/revit/v1/
|
||
```
|
||
|
||
Dadurch kann ein älteres Dynamo-Skript später noch mit einer neueren App-Version umgehen oder zumindest kontrolliert abgelehnt werden.
|
||
|
||
---
|
||
|
||
# 23. Langfristige Perspektive: Revit Add-in
|
||
|
||
Dynamo + Python ist für die erste Implementierung ideal, weil schnell getestet und angepasst werden kann.
|
||
|
||
Langfristig könnte daraus ein echtes Revit-Add-in in C#/.NET werden.
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
Revit Ribbon
|
||
|
||
┌──────── Leistungsbilanz ─────────┐
|
||
│ │
|
||
│ ↑ Daten übertragen │
|
||
│ ↓ Daten aus Leistungsbilanz │
|
||
│ │
|
||
│ Projekt verbinden │
|
||
│ Sync-Status │
|
||
│ │
|
||
└──────────────────────────────────┘
|
||
```
|
||
|
||
Wichtig ist deshalb, dass die API nicht speziell auf Dynamo zugeschnitten wird.
|
||
|
||
Ziel:
|
||
|
||
```text
|
||
heute:
|
||
Dynamo + Python
|
||
↓
|
||
gleiche REST API
|
||
|
||
später:
|
||
Revit Add-in C#
|
||
↓
|
||
gleiche REST API
|
||
```
|
||
|
||
---
|
||
|
||
# 24. Aktuell gewünschter Dynamo-Umfang
|
||
|
||
Für den ersten produktiven Revit-Export soll Codex ein Dynamo-Python-Skript vorschlagen, das mindestens folgende Daten aus `OST_ElectricalFixtures` ermittelt:
|
||
|
||
```text
|
||
revitModelId
|
||
ElementId
|
||
UniqueId
|
||
IFC GUID
|
||
Kategorie
|
||
Familie
|
||
Typ
|
||
MEP Raumnummer
|
||
MEP Raumname
|
||
```
|
||
|
||
Zusätzlich soll Codex anhand der aktuellen Leistungsbilanz-Datenstruktur prüfen, welche weiteren Felder bereits jetzt sinnvoll mitgegeben werden sollten.
|
||
|
||
Dazu könnten später gehören:
|
||
|
||
```text
|
||
Ebene
|
||
BMK
|
||
Leistung
|
||
cosPhi
|
||
Spannung
|
||
Anzahl
|
||
Kommentar
|
||
Stromkreis
|
||
Verteiler
|
||
weitere Shared Parameters
|
||
```
|
||
|
||
Diese zusätzlichen Felder sollen aber nicht willkürlich eingebaut werden, sondern aus der bestehenden Architektur und den fachlichen Anforderungen der Leistungsbilanz abgeleitet werden.
|
||
|
||
---
|
||
|
||
# 25. Anforderungen an das Dynamo-Python-Skript
|
||
|
||
Das Skript soll möglichst:
|
||
|
||
- ohne externe Dynamo-Packages funktionieren,
|
||
- nur Revit API / Dynamo-eigene Python-Möglichkeiten verwenden,
|
||
- mit der im Projekt eingesetzten Revit-/Dynamo-Version kompatibel sein,
|
||
- alle Elektroinstallationen im gesamten aktuellen Revit-Dokument lesen,
|
||
- nicht nur die aktive Ansicht betrachten,
|
||
- fehlende optionale Parameter tolerieren,
|
||
- verständliche Fehlermeldungen liefern,
|
||
- eine gut lesbare Statusausgabe an `OUT` zurückgeben,
|
||
- JSON mit UTF-8 erzeugen,
|
||
- HTTP-Requests ohne unnötige externe Python-Abhängigkeiten ausführen,
|
||
- Timeouts behandeln,
|
||
- API-Fehler auswerten,
|
||
- keinen Datenverlust verursachen.
|
||
|
||
Für spätere Writebacks muss das Skript Revit-Änderungen ausschließlich innerhalb gültiger Revit-Transactions durchführen.
|
||
|
||
---
|
||
|
||
# 26. Gewünschter Arbeitsauftrag an Codex
|
||
|
||
## Schritt 1 – Repository analysieren
|
||
|
||
Vor Änderungen zuerst:
|
||
|
||
1. `AGENTS.md` lesen.
|
||
2. Bestehende Architektur-Dokumentation lesen.
|
||
3. Datenmodell der Leistungsbilanz nachvollziehen.
|
||
4. Aktuelle Import-/CSV-Architektur untersuchen.
|
||
5. Vorhandene API-Routen analysieren.
|
||
6. Prüfen, ob bereits Entitäten oder Konzepte für:
|
||
- externe Modelle,
|
||
- Revit-Elemente,
|
||
- Linked Devices,
|
||
- Sync,
|
||
- Imports,
|
||
- Projekt-Historie
|
||
existieren.
|
||
7. Authentifizierung und Berechtigungssystem prüfen.
|
||
8. Bestehende Tests und Testkonventionen prüfen.
|
||
|
||
Noch keine größere Implementierung beginnen, bevor diese Analyse abgeschlossen ist.
|
||
|
||
---
|
||
|
||
## Schritt 2 – Bestehende Architektur gegen dieses Konzept abgleichen
|
||
|
||
Codex soll beantworten:
|
||
|
||
1. Welche vorhandenen Entitäten können wiederverwendet werden?
|
||
2. Brauchen wir überhaupt eine neue `RevitElement`-Entität?
|
||
3. Wie passt die Revit-Referenz in das bestehende `LinkedDevice`-/DeviceRow-Konzept?
|
||
4. Wo sollte das Sync-Verhalten im Backend liegen?
|
||
5. Wie soll die Modellidentität gespeichert werden?
|
||
6. Welche Felder sind Revit-Master?
|
||
7. Welche Felder sind Leistungsbilanz-Master?
|
||
8. Wie werden manuell überschriebene Werte geschützt?
|
||
9. Wie werden nicht mehr vorhandene Revit-Elemente behandelt?
|
||
10. Wie lässt sich das bestehende CSV-System sinnvoll weiterverwenden?
|
||
|
||
---
|
||
|
||
## Schritt 3 – Konkreten Zielentwurf erstellen
|
||
|
||
Codex soll danach einen konkreten Entwurf liefern für:
|
||
|
||
### Datenmodell
|
||
|
||
Mit tatsächlichen Namen passend zum Repository.
|
||
|
||
### API
|
||
|
||
Mit:
|
||
|
||
```text
|
||
HTTP Method
|
||
Route
|
||
Request DTO
|
||
Response DTO
|
||
Validierung
|
||
Fehlercodes
|
||
Authentifizierung
|
||
```
|
||
|
||
### Sync-Service
|
||
|
||
Mit klarer Verantwortung für:
|
||
|
||
```text
|
||
Create
|
||
Update
|
||
Unchanged
|
||
Missing
|
||
Deleted
|
||
Linking
|
||
Conflict handling
|
||
```
|
||
|
||
### Dynamo-Schnittstelle
|
||
|
||
Mit dem exakten JSON, das Dynamo senden bzw. empfangen soll.
|
||
|
||
---
|
||
|
||
## Schritt 4 – Dynamo-Skripte vorschlagen
|
||
|
||
Erst nachdem die Zielarchitektur feststeht, soll Codex konkrete Dynamo-Python-Skripte erstellen.
|
||
|
||
Mindestens:
|
||
|
||
### Script A – Revit → Leistungsbilanz
|
||
|
||
Funktionen:
|
||
|
||
```text
|
||
Revit-Modell-ID ermitteln
|
||
Electrical Fixtures sammeln
|
||
Daten auslesen
|
||
Payload erzeugen
|
||
JSON serialisieren
|
||
API aufrufen
|
||
Antwort auswerten
|
||
Status in Dynamo ausgeben
|
||
```
|
||
|
||
### Script B – Leistungsbilanz → Revit
|
||
|
||
Noch nicht zwingend sofort implementieren, aber vollständig konzipieren.
|
||
|
||
Funktionen:
|
||
|
||
```text
|
||
Writeback-Daten von API abrufen
|
||
Element über UniqueId finden
|
||
Allowlist-Mapping anwenden
|
||
Werte prüfen
|
||
Revit Transaction starten
|
||
Parameter schreiben
|
||
Ergebnis an API melden
|
||
Status ausgeben
|
||
```
|
||
|
||
### Optional Script C – Debug-/Offline-Export
|
||
|
||
Export des exakt gleichen Payloads als lokale JSON-Datei.
|
||
|
||
Damit kann die Schnittstelle auch ohne erreichbare API getestet werden.
|
||
|
||
---
|
||
|
||
# 27. Erwartete Ausgabe von Codex
|
||
|
||
Codex soll nach der Analyse **nicht sofort große Änderungen durchführen**, sondern zuerst eine strukturierte Empfehlung liefern.
|
||
|
||
Gewünschte Reihenfolge:
|
||
|
||
```text
|
||
1. Analyse des Ist-Zustands
|
||
2. Abweichungen / bereits vorhandene passende Architektur
|
||
3. Empfohlenes Zieldesign
|
||
4. Datenmodelländerungen
|
||
5. API-Design
|
||
6. Sync-Logik
|
||
7. Exaktes JSON-Schema
|
||
8. Vorschlag Dynamo Script A
|
||
9. Vorschlag Dynamo Script B
|
||
10. Migrations-/Implementierungsreihenfolge
|
||
11. Tests
|
||
12. Offene Entscheidungen
|
||
```
|
||
|
||
Bei Architekturentscheidungen soll Codex die einfachste robuste Lösung bevorzugen und unnötige neue Abstraktionen vermeiden.
|
||
|
||
---
|
||
|
||
# 28. Bevorzugte Implementierungsreihenfolge
|
||
|
||
Voraussichtlich sinnvoll:
|
||
|
||
```text
|
||
Phase 1
|
||
────────────────────────────
|
||
Austauschformat / DTO festlegen
|
||
|
||
Phase 2
|
||
────────────────────────────
|
||
Backend API für Revit-Snapshot
|
||
|
||
Phase 3
|
||
────────────────────────────
|
||
Persistierung und Upsert-Logik
|
||
|
||
Phase 4
|
||
────────────────────────────
|
||
Dynamo Revit → API
|
||
|
||
Phase 5
|
||
────────────────────────────
|
||
UI für importierte / nicht zugeordnete Revit-Elemente
|
||
|
||
Phase 6
|
||
────────────────────────────
|
||
Zuordnungs- und Override-Verhalten
|
||
|
||
Phase 7
|
||
────────────────────────────
|
||
Writeback API
|
||
|
||
Phase 8
|
||
────────────────────────────
|
||
Dynamo API → Revit
|
||
|
||
Phase 9
|
||
────────────────────────────
|
||
ggf. später Revit C# Add-in
|
||
```
|
||
|
||
---
|
||
|
||
# 29. Zentrale Architekturentscheidung
|
||
|
||
Die wichtigste Vorgabe lautet:
|
||
|
||
> Dynamo soll als Revit-Adapter dienen. Die eigentliche Fachlogik der Leistungsbilanz bleibt in der Leistungsbilanz-App.
|
||
|
||
Dynamo soll deshalb nicht entscheiden:
|
||
|
||
```text
|
||
welche Sicherung gewählt wird
|
||
welche Leitung verwendet wird
|
||
wie Stromkreise aufgebaut werden
|
||
wie Geräte gruppiert werden
|
||
welche Leistungswerte fachlich gültig sind
|
||
```
|
||
|
||
Dynamo liefert primär Revit-Daten und schreibt später explizit freigegebene Ergebnisse zurück.
|
||
|
||
Die fachliche Entscheidung bleibt in der Webapp.
|
||
|
||
---
|
||
|
||
# 30. Zielbild
|
||
|
||
```text
|
||
REVIT
|
||
│
|
||
Revit API
|
||
│
|
||
Dynamo / Python
|
||
│
|
||
JSON DTO
|
||
│
|
||
REST / HTTP
|
||
│
|
||
▼
|
||
Leistungsbilanz API
|
||
│
|
||
Sync Service
|
||
│
|
||
┌───────────┴───────────┐
|
||
│ │
|
||
Revit-Referenz Business Logic
|
||
│ │
|
||
└───────────┬───────────┘
|
||
│
|
||
DeviceRow
|
||
│
|
||
Circuit
|
||
│
|
||
Distributor
|
||
```
|
||
|
||
Später:
|
||
|
||
```text
|
||
Leistungsbilanz
|
||
│
|
||
Writeback
|
||
│
|
||
▼
|
||
Dynamo / Python
|
||
│
|
||
▼
|
||
Revit
|
||
```
|
||
|
||
Das Ziel ist keine möglichst komplexe Echtzeitkopplung, sondern eine robuste, nachvollziehbare und versionierbare Integration, die zunächst über Dynamo/Python funktioniert und später bei Bedarf durch ein natives Revit-Add-in ersetzt werden kann.
|