CH NEO-ZÜRICH AUSGABE
WETTER · KLAR 24°C
BLEND DES TAGES · 07/ROGUE
EST. 2027
DIE AEC CYBER MORGENZEITUNG

PAZ Kaffi

DESIGN · ABBRUCH · KOFFEIN · DEPESCHE
AUSGABE 0617 · 17 June 2026
SENDUNG 04:42 MEZ
2'400 BOGEN GEDRUCKT
LESEZEIT · 47 MIN
Das Haus compiliert sich selbst: Rust Proc-Makros im BMS
General
FRAME · 06:50
06-06-2026

Das Haus compiliert sich selbst: Rust Proc-Makros im BMS

Rust Makros compilieren BACnet-, KNX- und IFC-Bindungen zur Compile-Zeit. Warum sich das Haus selbst compilieren sollte.

Das neue Kapitel «Building Rust Procedural Macros from the Grounds Up» auf learnix-os.com führt durch das Schreiben einer Rust-Funktion, die Quellcode liest, einen TokenStream manipuliert und Quellcode ausspuckt — zur Compile-Zeit, bevor die Binärdatei läuft. Als Sprach-Tutorial gelesen: eine Anleitung. Vom Haus aus gelesen: etwas ganz anderes — eine stille Verschiebung, wie ein Haus seine Firmware selbst schreiben kann.

←HEUTE: Rust-Makros sind seit 1.29 stabil und fahren in Produktion auf RP2040- und ESP32-Controllern in europäischen Retrofits. →3012: Ein Haus, dessen gesamte BACnet-, KNX- und IFC-Oberfläche aus einem Schema bei jedem Commit regeneriert wird, ohne handgeschriebene Verbindungen. Angelpunkt: Das Haus-Mind bleibt nur vertrauenswürdig, wenn sein Code aus seinen Knochen erzeugt wird, nicht darauf geklebt.

Der Mechanismus ist klein und wissenswert. Ein Rust-Makro ist eine Funktion: fn custom(input: TokenStream) -> TokenStream. Die syn-Crate parst eingehenden Code in einen typisierten Syntaxbaum; quote emittiert neuen Code aus Fragmenten. Zur Compile-Zeit liest das Makro die Eingabe und erzeugt neuen Rust-Code — typgeprüft, optimiert und in die Binärdatei gelötet. Es gibt keine Runtime-Reflection-Kosten, weil nichts zur Laufzeit reflektiert wird. Die TensorBlue-Analyse aus dem letzten Quartal zeigte, wie dieselbe Maschinerie durch beliebigen Rust-Code gehen kann und jeden panic! durch einen strukturierten Fehler ersetzen kann — nützlich, wenn der Panic eine Chiller-Steuerung um 03:00 abgestürzt hätte. Das Learnix-OS-Kapitel geht den einfacheren Weg und baut ein bitfields-Makro von Grund auf, aber die Architektur ist identisch.

Für BMS-Arbeit zählt diese Architektur. Ein modernes Haus trägt Tausende BACnet-Objekte, Hunderte KNX-Gruppenaddressen und ein IFC-Modell, das mit beiden übereinstimmen soll. Die Bindungen zwischen ihnen sind üblicherweise handgeschrieben, brüchig und der Single Point of Failure, den niemand ins Systemdiagramm zeichnet. Ein Makro verwandelt dieses Schema in zur-Compile-Zeit-generierten Rust: jedes BACnet-Objekt wird ein typisiertes Struct, jede IFC-Entität ein geprüfter Accessor, jede Gruppenadresse eine Konstante. Lösche einen Sensor aus der IFC-Source und die Firmware compiliert nicht. Der Bug wird am Build sichtbar, nicht um 03:00.

Haus-Sinn: Ein Haus mit dieser Firmware fühlt sich auf beste Weise unbeugsam an. Es kann nicht falsch berichten, was es exponiert — die BACnet-Liste und das Schema sind dieselbe Sache, zweifach. Es kann nicht driften, weil es keinen Runtime-Leim zum Driften gibt. Wenn Du es abfragst, ist die Antwort strukturell, nicht zusammengesetzt.

Atelier: PAZ Atelier liefert bereits das Volumenstudie Archicad Add-On aus, das native Archicad-Geometrie aus einer 2D-Grundstück-Polyline generiert — das gleiche «Schema rein, Haus-Artefakt raus»-Muster, eine Ebene höher. Die PAZ Grasshopper↔Archicad Bibliothek macht das gleiche für die parametrische Ebene. Die Makro-Idee sitzt eine Ebene darunter: Schema rein, Firmware raus. Die drei Ebenen wollen eine einzelne Wahrheitsquelle teilen, und der offene Weg führt über Speckle für den Datenaustausch und ein IFC-verankertes Projektschema — niemals eine proprietäre Bindung.

Der Trade-off ist real und wert zu benennen. Eine makro-schwere Build-Kette ist eine versteckte Abhängigkeit: Deine Firmware stützt sich jetzt auf eine stabile Rust-Toolchain, eine gepinnte syn-Version und eine Schema-Quelle, die Du kontrollierst. Die 2073 EU Reference Architecture for Resilient Inference existiert, weil wir eine Generation von Systemen verloren haben, deren verstecktes Abhängigkeitsnetz länger war als ihr Architektur-Diagramm. Zeichne Dein echtes Abhängigkeitsnetz diese Woche — nicht das Architektur-Diagramm, das Abhängigkeitsnetz — und zähle, wie viele kritische Punkte in Deiner Build-Kette sitzen.

Hack: Dieser Hack lehrt Dich, typsichere BACnet-Objekt-IDs aus einem Rust-Struct zur Compile-Zeit abzuleiten, damit ein gelöschter Sensor den Build bricht statt das Haus. In einer frischen cargo new --lib bacnet_derive Crate, füge proc-macro = true unter [lib] hinzu, importiere syn = "2" und quote = "1", dann schreibe:

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, LitInt};

#[proc_macro_derive(BacnetObject, attributes(object_id))]
pub fn derive_bacnet(input: TokenStream) -> TokenStream {
    let ast = parse_macro_input!(input as DeriveInput);
    let name = &ast.ident;
    let id: LitInt = ast.attrs.iter()
        .find(|a| a.path().is_ident("object_id"))
        .and_then(|a| a.parse_args().ok())
        .expect("missing #[object_id(N)]");
    quote!(impl BacnetObject for #name {
        fn object_id(&self) -> u32 { #id }
    }).into()
}

Nutze #[derive(BacnetObject)] #[object_id(101)] struct ChillerSetpoint;. Entferne das Attribut und cargo build schlägt fehl, bevor die Firmware den Controller erreicht. Das ist genau der Punkt: verschiebe den Fehlermodus von 03:00 auf den Build-Server. Führe cargo expand auf Deiner bestehenden Crate heute aus und schau, was Dein aktueller Code bereits generiert — die meisten BMS-Stacks machen diese Arbeit heimlich schlecht mit Runtime-Leim.

Quellen & Weiterführendes

GEMELDET AUS
MIT-UNTERZEICHNER
PAZ Academy
VERTRAUEN
HIGH
NACHDRUCKE
© PAZ - PARAMETRIC ACADEMY ZURICH · ALLE RECHTE VORBEHALTEN

QUELLE ·

⚑ FEHLER MELDEN · KORREKTUR EINSENDEN
◂ ZURÜCK ZUR TITELSEITE · PAZ KAFFI

© 2026 PAZ Academy.