Ein Funk/KNX Gateway für einen Zehnder Badheizkörper.
  • C 59.8%
  • C++ 37.6%
  • CMake 1.5%
  • Python 0.7%
  • HTML 0.4%
Find a file
2026-05-23 15:05:36 +02:00
.claude Claude-Settings aktualisiert/aufgenommen. 2026-05-19 19:49:06 +02:00
.vscode VS Code Konfigurationsfiles aufgenommen (Build in VS Code) 2026-05-20 16:43:09 +02:00
antenna Gitignore aktualisiert und Dateien zur Simulation der Helixantenne aufgenommen. 2026-05-22 09:01:50 +02:00
boards/custom/zehnder_knx_gw Power Management Stufe 2: KNX-UART auf LPUART1, Wake aus Stop 1/2 2026-05-23 14:21:02 +02:00
doc Datenblatt des STM32L431KC aufgenommen. 2026-05-23 14:09:43 +02:00
dts/bindings RFTransceiver-Klasse fuer SPIRIT1-Anbindung aufgenommen. 2026-05-18 17:11:10 +02:00
hardware/knx_zehnder_gw Kicad-Dateien für Leiterplatte aufgenommen. 2026-05-23 15:04:37 +02:00
lib KNX-Footprint: Coupler-Quellen aus dem libknx-Glob ausschliessen 2026-05-23 14:54:20 +02:00
scripts Umlaute in den Quellen ersetzt und Umlaute-Ersetzungs-Skript aufgenommen. 2026-05-21 20:13:17 +02:00
src KNX-Transceiver: Umstellung auf NCN5121 (Nachfolgebaustein, protokollkompatibel) 2026-05-23 13:58:29 +02:00
tests RFTransceiver: Tx/Rx-Aktivitaets-LEDs mit Pulse-und-Aus-Halt-Logik 2026-05-22 19:11:58 +02:00
.gitignore Gitignore erneut angepasst. 2026-05-23 15:05:36 +02:00
.gitmodules crypto-algorithms-Submodule entfernt. 2026-05-18 16:58:05 +02:00
.mcp.json MCP-Port korrigiert. 2026-05-17 19:34:16 +02:00
CLAUDE.md KNX-Transceiver: Umstellung auf NCN5121 (Nachfolgebaustein, protokollkompatibel) 2026-05-23 13:58:29 +02:00
CMakeLists.txt Application: Pairing-Taster als zweiter Weg neben Auto-Pairing 2026-05-22 19:30:07 +02:00
Kconfig Zephyr/CMake-Grundgeruest aufgenommen (Phase 2). 2026-05-18 16:40:42 +02:00
prj.conf RAM-Footprint: PSA-Key-Slots von 16 auf 3 reduzieren 2026-05-23 14:38:13 +02:00
prj_release.conf KNX-Transceiver: Umstellung auf NCN5121 (Nachfolgebaustein, protokollkompatibel) 2026-05-23 13:58:29 +02:00
README.md KNX-Transceiver: Umstellung auf NCN5121 (Nachfolgebaustein, protokollkompatibel) 2026-05-23 13:58:29 +02:00

Zehnder KNX Gateway

KNX-Gateway für den proprietären Funkstandard, mit dem Zehnder-Badheizkörper per Funkfernbedienung gesteuert werden. Das Gateway sitzt zwischen einem KNX-TP1-Bus und dem Heizkörper und bildet beide Richtungen ab: KNX-Telegramme (Mode, Sollwerte, Boost, Zeit/Datum, Sperre) werden in den Funk-Protokollstack übersetzt, und Status-Rückmeldungen des Heizkörpers (Heizbedarf, Fenster-offen- Erkennung, Boost-Status, Fehlercode) werden auf KNX-Group-Objects gespiegelt.

Funktionsumfang

  • 17 KNX-Datenpunkte (siehe src/Application.h für die vollständige Liste): HVAC-Mode (DPT 20.102), Soll-/Ist-Temperaturen (DPT 9.001), Boost-Steuerung, Wochenprogramm-Sync, RTC-Sync, Sperre.
  • Pairing mit dem Heizkörper über Diffie-Hellman-Schlüsselaustausch (zweite Methode neben dem Compile-Time-Default für Out-of-the-Box-Betrieb).
  • Persistenz in Flash (NVS): Session-Key, Auth-Paket, UID-Fingerprint.
  • Power Management (Stufe 1): SoC geht im Idle in Sleep/Stop 0; KNX-Loop und RFProtocol sind event-getrieben (UART-IRQ, GPIO-IRQ, Timer wecken).
  • Sofortige Reaktion auf KNX-Schreibvorgänge (Mode, Setpoints, Boost): KO- Änderungen erscheinen innerhalb weniger 100 ms am Heizkörper — kein Warten auf den nächsten Sync-Burst (FEATURE_IMMEDIATE_SEND_ON_CHANGE).

Hardware

Komponente Typ
Mikrocontroller STM32L431KC (Cortex-M4F, UFQFPN32)
Funk-Transceiver STMicroelectronics SPIRIT1 (868 MHz)
KNX-Transceiver ON Semiconductor NCN5121
Flash / RAM 256 KB Flash, 64 KB SRAM

Die SPIRIT1-Konfiguration ist mit STMicroelectronics' Tool SPIRIT1 DK generiert und unter src/generated/spirit1/ abgelegt. Die KNX-Stack-Headers (Communication Objects, Parameter) sind aus dem ETS-Produkt erzeugt und liegen unter src/generated/knx/. Verwendetes Tool: MyKaenx.

Architektur

Die Software ist in C++20 geschrieben und in mehrere voneinander entkoppelte Klassen aufgeteilt:

  • Application — KNX-Bridge. Übersetzt zwischen KNX-Group-Objects und Heater-API. Einzige Stelle, die sowohl den KNX-Stack als auch den Heater kennt.
  • Heater — abstrakte Sicht auf den Heizkörper. Hält Zustand (Mode, Setpoints, Boost, Status) und bietet Observer-Callbacks für Statusänderungen.
  • RFProtocol — Implementierung des proprietären Funk-Protokolls (Discovery, Auth, Burst-Sync, Pairing). State-Machine in eigenem Thread.
  • RFTransceiver — Hardware-Abstraktion für den SPIRIT1 (SPI + GPIO-IRQs). Wird vom RFProtocol benutzt; Anwendungs-Code spricht ihn nicht direkt an.
  • Crypto — AES-128, HMAC-SHA-256, CRC8, DH-Schlüsselaustausch.
  • SessionStore / NvsSessionStorage — Flash-Persistenz für Session-Material.

Die Reverse-Engineering-Ergebnisse, auf denen das Funkprotokoll basiert, sind in doc/Implementation_guide.md zusammengefasst. Übergreifende Richtlinien für die Codebase stehen in CLAUDE.md.

Voraussetzungen

Das Projekt hat zwei getrennte Build-Wege, die in unterschiedlichen Umgebungen laufen:

Ziel Umgebung Toolchain
Firmware (STM32L431KC) Windows nativ (PowerShell) Zephyr SDK + ARM-Toolchain
Test-Suite (GoogleTest) WSL2/Ubuntu (native_sim) System-gcc + Zephyr SDK minimal

Hintergrund: Zephyrs native_sim-Board basiert auf der POSIX-Architektur und läuft unter Windows nicht; deshalb laufen die Tests in WSL. Die Firmware dagegen wird auf Windows gebaut, weil dort die VS-Code-Integration und die ARM-Toolchain bereits eingerichtet sind und der Speed des nativen Builds besser ist als über die 9P-Mount-Brücke.

Setup auf einem leeren Rechner

Schritt 1: Repository auschecken

git clone <repo-url> KNX_Zehnder_Interface
cd KNX_Zehnder_Interface

Im Folgenden wird das Wurzelverzeichnis des Repos als <repo> bezeichnet.

Schritt 2: Toolchain für Firmware-Builds (Windows)

Das Firmware-Target braucht Zephyr und die ARM-Toolchain nativ auf Windows. Empfohlene Versionen: Zephyr 4.4, Zephyr SDK 1.0.1.

  1. Python 3.10+ installieren (z. B. aus dem Microsoft Store).

  2. west und Zephyr-Python-Abhängigkeiten in einem dedizierten Venv:

    python -m venv "$env:USERPROFILE\zephyrproject-venv"
    & "$env:USERPROFILE\zephyrproject-venv\Scripts\Activate.ps1"
    pip install --upgrade pip wheel west
    
  3. Zephyr-Workspace anlegen (kann unter beliebigem Pfad liegen — der folgende Befehl legt ihn unter %USERPROFILE%\zephyrproject an):

    west init "$env:USERPROFILE\zephyrproject"
    Set-Location "$env:USERPROFILE\zephyrproject"
    west update                                  # zieht alle Module, dauert mehrere Minuten
    pip install -r zephyr\scripts\requirements.txt
    
  4. Zephyr SDK (volle Variante mit ARM-Toolchain) von https://github.com/zephyrproject-rtos/sdk-ng/releases herunterladen und installieren. Beim Setup das Häkchen für „Register as CMake package" aktiv lassen.

  5. Umgebungsvariablen dauerhaft setzen (in PowerShell):

    [Environment]::SetEnvironmentVariable("ZEPHYR_BASE",
        "$env:USERPROFILE\zephyrproject\zephyr", "User")
    

    Nach dem Setzen die PowerShell neu öffnen. Falls die ARM-Toolchain separat liegt (nicht über das Zephyr-SDK installiert), zusätzlich:

    [Environment]::SetEnvironmentVariable("ZEPHYR_TOOLCHAIN_VARIANT",
        "gnuarmemb", "User")
    [Environment]::SetEnvironmentVariable("GNUARMEMB_TOOLCHAIN_PATH",
        "<Pfad zur Compiler-Toolchain ohne bin>", "User")
    

Schritt 3: Toolchain für die Test-Suite (WSL2/Ubuntu)

Die Tests brauchen Linux. Falls noch keine Ubuntu-Distro installiert ist (in PowerShell auf dem Windows-Host):

wsl --install -d Ubuntu

Anschließend in die WSL-Shell wechseln (wsl -d Ubuntu). Alle weiteren Schritte laufen innerhalb von Ubuntu.

  1. System-Pakete (Zephyr-Voraussetzungen + native_sim-Abhängigkeiten):

    sudo apt update
    sudo apt install --no-install-recommends \
        git cmake ninja-build gperf ccache dfu-util device-tree-compiler wget \
        python3-dev python3-pip python3-setuptools python3-tk python3-wheel python3-venv \
        xz-utils file make gcc g++ libsdl2-dev libmagic1
    
  2. Python-Venv + west:

    python3 -m venv ~/zephyrproject-venv
    source ~/zephyrproject-venv/bin/activate
    pip install --upgrade pip wheel west
    
  3. Zephyr-Workspace:

    west init ~/zephyrproject
    cd ~/zephyrproject
    west update                       # zieht alle Module, dauert 5-10 Min
    pip install -r ~/zephyrproject/zephyr/scripts/requirements.txt
    
  4. Zephyr SDK (minimal) — keine Target-Toolchain nötig, weil native_sim den System-gcc benutzt:

    cd ~
    SDK_VER=$(cat ~/zephyrproject/zephyr/SDK_VERSION)
    wget "https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v${SDK_VER}/zephyr-sdk-${SDK_VER}_linux-x86_64_minimal.tar.xz"
    tar xf "zephyr-sdk-${SDK_VER}_linux-x86_64_minimal.tar.xz"
    rm   "zephyr-sdk-${SDK_VER}_linux-x86_64_minimal.tar.xz"
    cd   "zephyr-sdk-${SDK_VER}"
    yes | ./setup.sh -h -c            # installiert Host-Tools, registriert CMake-Paket
    
  5. Umgebungsvariablen an ~/.bashrc anhängen, damit sie in jedem neuen Terminal verfügbar sind:

    cat >> ~/.bashrc << 'EOF'
    
    # --- Zephyr / KNX_Zehnder_Interface ---
    export ZEPHYR_BASE="$HOME/zephyrproject/zephyr"
    alias zephyr-venv="source $HOME/zephyrproject-venv/bin/activate"
    # --- /Zephyr ---
    EOF
    

    In neuen Shells dann zephyr-venv aufrufen, um das Venv zu aktivieren.

Firmware bauen (Windows)

Das Board ist ein Custom-Board im Repo (boards/custom/zehnder_knx_gw/), deshalb muss BOARD_ROOT auf das Repo-Wurzelverzeichnis zeigen.

Initial-Build (aus dem Repo-Wurzelverzeichnis heraus):

west build -b zehnder_knx_gw -d build-fw . -- -DBOARD_ROOT=.

Inkrementeller Build (nutzt die im Build-Ordner gespeicherte Konfiguration):

west build -d build-fw

Das Ergebnis liegt unter build-fw/zephyr/zephyr.elf (plus zephyr.bin, zephyr.hex). Aktuelle Größen liegen bei ca. 60 % Flash und 63 % RAM.

compile_commands.json für die IDE-Integration ist automatisch in build-fw/compile_commands.json verfügbar (über die Default-CMake-Konfiguration des Projekts).

Flashen auf das Board

Mit einem ST-Link über west flash (vorausgesetzt OpenOCD/STM32CubeProgrammer ist im PATH):

west flash -d build-fw

Tests bauen und ausführen (WSL/Ubuntu)

Wichtig: Das Build-Verzeichnis muss außerhalb von /mnt/c liegen, sonst ist der Build wegen des 9P-Mounts 1020× langsamer. Quellen dürfen auf /mnt/c bleiben.

In der WSL-Shell:

zephyr-venv                                # Venv aktivieren
cd /mnt/c/<Pfad/zum/Repo>                  # Source-Tree bleibt auf /mnt/c
west build -p auto -b native_sim/native/64 -d ~/build-knx-tests tests
~/build-knx-tests/zephyr/zephyr.exe

Beim ersten Lauf lädt CMake via FetchContent GoogleTest v1.14.0 herunter (ca. 23 MB); spätere Builds nutzen den Cache.

Hinweise zur Board-Wahl: Wir nehmen explizit native_sim/native/64 (64-Bit). Das Default-native_sim (32-Bit) kollidiert mit dem 64-Bit-GoogleTest beim Linken.

GoogleTest-Filter

native_sim verlangt, dass GoogleTest-Flags hinter -testargs stehen:

~/build-knx-tests/zephyr/zephyr.exe -testargs --gtest_list_tests
~/build-knx-tests/zephyr/zephyr.exe -testargs --gtest_filter='Crc8Test.*'
~/build-knx-tests/zephyr/zephyr.exe -testargs --gtest_brief=1

Weitere Details (was im Einzelnen getestet wird, Tipps für neue Tests) stehen in tests/README.md.

Tests aus PowerShell anstoßen

Praktisch für CI-artige Skripte auf dem Windows-Host:

wsl -d Ubuntu -e sh -c 'export PATH=$HOME/zephyrproject-venv/bin:$PATH; export ZEPHYR_BASE=$HOME/zephyrproject/zephyr; cd /mnt/c/<Pfad/zum/Repo> && $HOME/zephyrproject-venv/bin/west build -b native_sim/native/64 -d $HOME/build-knx-tests tests && $HOME/build-knx-tests/zephyr/zephyr.exe -testargs --gtest_brief=1'

Distro explizit wählen (-d Ubuntu); die Default-WSL-Distro auf manchen Systemen ist docker-desktop und kann das nicht ausführen.

VS Code

Für Firmware-Entwicklung (Windows-Seite)

Im integrierten Terminal sind ZEPHYR_BASE und ggf. ZEPHYR_TOOLCHAIN_VARIANT nach dem Setup im User-Environment direkt verfügbar. Empfohlene Extensions: ms-vscode.cpptools, ms-vscode.cmake-tools. compile_commands.json aus build-fw/ verweisen lassen.

Für Test-Entwicklung (WSL-Seite)

  1. Im Windows-VS-Code die Extension WSL (ms-vscode-remote.remote-wsl) installieren.
  2. F1WSL: Reopen Folder in WSL → Distro Ubuntu wählen. Alle Sprachserver, Terminals und Debugger laufen ab jetzt serverseitig in Ubuntu.
  3. Empfohlene Extensions WSL-seitig nachinstallieren: ms-vscode.cpptools, ms-vscode.cmake-tools, ms-python.python.

Verzeichnisstruktur

.
├── boards/custom/zehnder_knx_gw/   # Custom-Board-Definition (DTS, defconfig)
├── doc/                            # Projekt-Doku + Datenblätter
│   └── Implementation_guide.md     # Reverse-Engineering-Ergebnis (Funkprotokoll)
├── lib/
│   ├── knx/                        # KNX-Stack (thelsing/knx, Submodul)
│   ├── knx-zephyr-platform/        # KNX-Stack-Plattform-Adapter für Zephyr
│   └── spirit1/                    # SPIRIT1-Bibliothek (STM)
├── src/
│   ├── generated/                  # autogenerierte Header (SPIRIT1, KNX)
│   ├── Application.{h,cpp}         # KNX-Bridge
│   ├── Heater.{h,cpp}              # Heizkörper-Abstraktion
│   ├── RFProtocol.{h,cpp}          # Funk-Protokoll-State-Machine
│   ├── RFTransceiver.{h,cpp}       # SPIRIT1-HW-Abstraktion
│   ├── Crypto.{h,cpp}              # AES/HMAC/CRC/DH
│   └── ...
├── tests/                          # GoogleTest-Suite (eigene Zephyr-App)
├── CLAUDE.md                       # übergreifende Codebase-Richtlinien
├── prj.conf                        # Anwendungs-Kconfig
└── README.md

Weitere Dokumentation

  • CLAUDE.md — übergreifende Konventionen (Code-Stil, Sprache, Test-Pflicht, Architekturentscheidungen).
  • doc/Implementation_guide.md — Detail- Dokumentation des Funkprotokolls (Pakettypen, Verschlüsselung, Pairing-Ablauf, Burst-Sequenzen).
  • tests/README.md — Test-Suite im Detail (welche Module, Vektor-Quellen, native_sim-Schalter).
  • src/AppConfig.h — Feature-Schalter der Anwendung (FEATURE_IMMEDIATE_SEND_ON_CHANGE, FEATURE_SPIRIT1_AUTO_SLEEP).