Dieses Dokument beschreibt die Coding-Richtlinien für das Pool-Controller Projekt, um Super-Linter Fehler zu vermeiden und Best Practices für ESP32 Entwicklung mit PlatformIO zu befolgen.
- Zeilenlänge: Maximal 130 Zeichen (definiert in
.clang-format) - Einrückung: 2 Leerzeichen (keine Tabs)
- Klammern: K&R-Stil (öffnende Klammer auf derselben Zeile)
- Pointer-Ausrichtung: Links (
int* ptrstattint *ptr)
// FALSCH
int x = 5;// Kommentar
// RICHTIG
int x = 5; // Kommentar (mindestens 2 Leerzeichen)// FALSCH
if(condition){
doSomething();
}
// RICHTIG
if (condition) {
doSomething();
}// FALSCH
namespace PoolController
{
namespace Detail {
// code
}
}
// RICHTIG
namespace PoolController {
namespace Detail {
// code
}
}// FALSCH
static Context context { };
// RICHTIG
static Context context{};// FALSCH
TimeChangeRule *tcr = NULL;
// RICHTIG
TimeChangeRule* tcr = nullptr;// FALSCH
const char* cTimezone = "timezone";
const char* cTimezoneName = "Timezone";
// RICHTIG (clang-format richtet automatisch aus)
const char* cTimezone = "timezone";
const char* cTimezoneName = "Timezone";
// Aber achte darauf, dass AlignConsecutiveDeclarations aktiviert istFühre vor jedem Commit aus:
# Alle C++ Dateien formatieren
clang-format -i src/**/*.cpp src/**/*.hpp
# Oder einzelne Datei
clang-format -i src/PoolController.cpp
# Prüfen ohne Änderungen
clang-format --dry-run --Werror src/**/*.cpp- Maximal 80 Zeichen für cpplint (strenger als clang-format)
- Lange Kommentare über mehrere Zeilen aufteilen
// FALSCH
unsigned long timestamp;
long value;
// RICHTIG
uint32_t timestamp; // Feste Breite, plattformunabhängig
int32_t value;// Verwende #pragma once statt Include-Guards
#pragma once
// Oder klassische Guards
#ifndef POOL_CONTROLLER_MODULE_HPP
#define POOL_CONTROLLER_MODULE_HPP
// ...
#endif // POOL_CONTROLLER_MODULE_HPP- Einrückung: 2 Leerzeichen für alle Dateien
- Keine Tabs: Immer Leerzeichen verwenden
- Trailing Whitespace: Entfernen
- Final Newline: Immer einfügen
- Charset: UTF-8
# Immer doppelte Anführungszeichen
name: "Workflow Name"
# Lange Zeilen mit | oder > aufteilen
run: >
command with many
arguments- "Wi-Fi" (not "Wi-Fi" - note the hyphen)
- URLs in spitze Klammern:
<https://example.com>
# 2 Leerzeichen für Einrückung
[env:esp32dev]
lib_deps =
me-no-dev/Homie@^3.0.0
https://github.com/me-no-dev/ESPAsyncWebServer.git// Vermeide große Stack-Allocations
char buffer[1024]; // Könnte Stack Overflow verursachen
// Besser: Heap-Allocation oder kleinere Puffer
String buffer;
buffer.reserve(1024);// FALSCH - Fragmentiert Heap
String result = "";
for (int i = 0; i < 100; i++) {
result += String(i);
}
// RICHTIG - Reserve Speicher im Voraus
String result;
result.reserve(300); // Schätze benötigten Platz
for (int i = 0; i < 100; i++) {
result += String(i);
}// Nutze yield() in langen Schleifen
for (int i = 0; i < 10000; i++) {
// Arbeit
if (i % 100 == 0) {
yield(); // Gibt ESP Zeit für WiFi/System-Tasks
}
}// Prüfe Verbindungsstatus
if (WiFi.status() == WL_CONNECTED) {
// Netzwerk-Operation
}
// Verwende WiFi.isConnected() für ESP32
if (WiFi.isConnected()) {
// Netzwerk-Operation
}# FALSCH - Package-Name mit Leerzeichen
lib_deps = me-no-dev/ESP Async WebServer @ 1.2.3
# RICHTIG - GitHub URL verwenden
lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git# lib_ignore verwenden, um Konflikte zu vermeiden
[env:esp32dev]
lib_ignore = ESP Async WebServer # Ignoriert Space-Variante
lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git# ESP32 verwendet AsyncTCP (ohne "ESP" Präfix)
# ESPAsyncWebServer bringt diese automatisch mit!# Debug-Informationen
build_flags =
-DDEBUG_ESP_PORT=Serial
-DDEBUG_ESP_CORE
# Release-Optimierung
build_flags =
-Os # Optimiere für Größemonitor_speed = 115200
monitor_filters = esp32_exception_decoder # Für ESP32# Vor jedem Commit ausführen:
# 1. Formatiere C++ Code
clang-format -i src/**/*.cpp src/**/*.hpp
# 2. Prüfe EditorConfig
# (wird automatisch von Super-Linter gemacht)
# 3. Teste lokale Compilation
pio run -e esp32dev# Format: <type>: <subject>
fix: Correct clang-format violations in PoolController.cpp
feat: Add NTP server configuration support
docs: Update coding guidelines
refactor: Improve memory usage in Timer class
- EditorConfig: Datei-Formatierung
- YAML: GitHub Actions Workflows
- Markdown: Dokumentation
- CPP: C++ Code (clang-format)
- CHECKOV: Zu viele False Positives (manuell validiert)
# Via mega-linter-runner (empfohlen)
npx mega-linter-runner --flavor c_cpp --remove-container
# Oder via Docker direkt (c_cpp flavor)
docker run --rm -v $(pwd):/tmp/lint:rw \
-e MEGALINTER_CONFIG=.mega-linter.yml \
ghcr.io/oxsecurity/megalinter-c_cpp:v9
# Oder via Docker (vollständiges Image)
docker run --rm -v $(pwd):/tmp/lint:rw \
-e MEGALINTER_CONFIG=.mega-linter.yml \
ghcr.io/oxsecurity/megalinter:v9# Tabs durch Leerzeichen ersetzen
find src -name "*.cpp" -o -name "*.hpp" | xargs sed -i 's/\t/ /g'# Entferne trailing whitespace
find . -name "*.cpp" -o -name "*.hpp" | xargs sed -i 's/[[:space:]]*$//'// Lange Zeilen umbrechen
// VORHER
static const char* veryLongVariableName = "This is a very long string that exceeds the line limit";
// NACHHER
static const char* veryLongVariableName =
"This is a very long string that exceeds the line limit";# Automatisch beheben
clang-format -i <file>// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.insertSpaces": true,
"editor.tabSize": 2,
"C_Cpp.clang_format_style": "file",
"C_Cpp.clang_format_fallbackStyle": "LLVM",
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true
}- C/C++ (Microsoft)
- PlatformIO IDE
- EditorConfig for Visual Studio Code
- Prettier (für YAML/Markdown)
- Alle C++ Dateien mit clang-format formatiert
- Keine Tabs, nur Leerzeichen (2 Spaces)
- Kein trailing whitespace
- Zeilenlänge beachtet (80 für cpplint, 130 für clang-format)
- Fixed-width Typen verwendet (uint32_t statt unsigned long)
- Alle Tests laufen erfolgreich
- PlatformIO builds erfolgreich (beide Plattformen)
- Super-Linter CI läuft erfolgreich durch