- C 59.8%
- C++ 37.6%
- CMake 1.5%
- Python 0.7%
- HTML 0.4%
| .claude | ||
| .vscode | ||
| antenna | ||
| boards/custom/zehnder_knx_gw | ||
| doc | ||
| dts/bindings | ||
| hardware/knx_zehnder_gw | ||
| lib | ||
| scripts | ||
| src | ||
| tests | ||
| .gitignore | ||
| .gitmodules | ||
| .mcp.json | ||
| CLAUDE.md | ||
| CMakeLists.txt | ||
| Kconfig | ||
| prj.conf | ||
| prj_release.conf | ||
| README.md | ||
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.hfü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.
-
Python 3.10+ installieren (z. B. aus dem Microsoft Store).
-
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 -
Zephyr-Workspace anlegen (kann unter beliebigem Pfad liegen — der folgende Befehl legt ihn unter
%USERPROFILE%\zephyrprojectan):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 -
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.
-
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.
-
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 -
Python-Venv + west:
python3 -m venv ~/zephyrproject-venv source ~/zephyrproject-venv/bin/activate pip install --upgrade pip wheel west -
Zephyr-Workspace:
west init ~/zephyrproject cd ~/zephyrproject west update # zieht alle Module, dauert 5-10 Min pip install -r ~/zephyrproject/zephyr/scripts/requirements.txt -
Zephyr SDK (minimal) — keine Target-Toolchain nötig, weil
native_simden System-gccbenutzt: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 -
Umgebungsvariablen an
~/.bashrcanhä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 --- EOFIn neuen Shells dann
zephyr-venvaufrufen, 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/cliegen, sonst ist der Build wegen des 9P-Mounts 10–20× langsamer. Quellen dürfen auf/mnt/cbleiben.
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. 2–3 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)
- Im Windows-VS-Code die Extension WSL (
ms-vscode-remote.remote-wsl) installieren. F1→ WSL: Reopen Folder in WSL → Distro Ubuntu wählen. Alle Sprachserver, Terminals und Debugger laufen ab jetzt serverseitig in Ubuntu.- 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).