Zum Inhalt springen

← Router-Modi | Inhaltsverzeichnis | Weiter: Hauptanwendung →

5. Modul-APIs und Datenstrukturen



5.1 RouterController API

Dateien:
- components/acrouter_hal/include/RouterController.h
- components/acrouter_hal/src/RouterController.cpp

Entwurfsmuster: Singleton


Instanz abrufen

cpp
RouterController& router = RouterController::getInstance();


Initialisierung

begin()

cpp
bool begin(DimmerHAL* dimmer, DimmerChannel channel = DimmerChannel::CHANNEL_1);

Beschreibung: Controller mit Dimmer-Bindung initialisieren.

Parameters:
- dimmer - pointer to initialized DimmerHAL
- channel - dimmer channel (CHANNEL_1 or CHANNEL_2)

Rückgabe: true bei Erfolg, false bei Fehler

Beispiel:

cpp
DimmerHAL& dimmer = DimmerHAL::getInstance();
RouterController& router = RouterController::getInstance();

dimmer.begin();
if (router.begin(&dimmer, DimmerChannel::CHANNEL_1)) {
    Serial.println("RouterController initialized");
} else {
    Serial.println("RouterController init failed");
}


Modusverwaltung

setMode()

cpp
void setMode(RouterMode mode);

Beschreibung: Betriebsmodus des Controllers festlegen.

Parameters:
- mode - one of 6 modes (OFF=0, AUTO=1, ECO=2, OFFGRID=3, MANUAL=4, BOOST=5)

Beispiel:

cpp
router.setMode(RouterMode::AUTO);    // Automatic mode
router.setMode(RouterMode::MANUAL);  // Manual mode

getMode()

cpp
RouterMode getMode() const;

Beschreibung: Aktuellen Betriebsmodus abfragen.

Rückgabe: Aktueller RouterMode

Beispiel:

cpp
RouterMode current = router.getMode();
if (current == RouterMode::AUTO) {
    Serial.println("Running in AUTO mode");
}


Steuerungsparameter

setControlGain()

cpp
void setControlGain(float gain);

Beschreibung: Proportionalkoeffizient des Reglers (Kp) festlegen.

Parameters:
- gain - gain coefficient (10.0 - 1000.0)

Effect:
- Lower Kp � faster response, possible oscillations
- Higher Kp � slower response, more stable

Beispiel:

cpp
router.setControlGain(200.0f);  // Standard value
router.setControlGain(100.0f);  // Faster response
router.setControlGain(400.0f);  // Slower, more stable

getControlGain()

cpp
float getControlGain() const;

Rückgabe: Aktueller Kp-Wert

setBalanceThreshold()

cpp
void setBalanceThreshold(float threshold);

Beschreibung: Gleichgewichtsschwelle in Watt festlegen.

Parameters:
- threshold - threshold in W (typically 5.0 - 50.0)

Effect:
- If |P_grid| < threshold, system is considered balanced
- Lower threshold � more accurate balance, more switching
- Higher threshold � less switching, less accurate balance

Beispiel:

cpp
router.setBalanceThreshold(10.0f);  // �10 W considered balanced
router.setBalanceThreshold(20.0f);  // �20 W for larger loads

getBalanceThreshold()

cpp
float getBalanceThreshold() const;

Rückgabe: Aktuelle Gleichgewichtsschwelle (W)



Manuelle Steuerung (MANUAL-Modus)

setManualLevel()

cpp
void setManualLevel(uint8_t percent);

Beschreibung: Feste Dimmer-Stufe für den MANUAL-Modus festlegen.

Parameters:
- percent - dimmer level 0-100%

Beispiel:

cpp
router.setMode(RouterMode::MANUAL);
router.setManualLevel(75);  // Set to 75%

getManualLevel()

cpp
uint8_t getManualLevel() const;

Rückgabe: Eingestellte Stufe für MANUAL-Modus



Hauptaktualisierungsschleife

update()

cpp
void update(const PowerMeterADC::Measurements& measurements);

Beschreibung: Hauptregelungsfunktion. Wird automatisch aus dem PowerMeterADC-Callback alle 200 ms aufgerufen.

Parameters:
- measurements - structure with power measurements

Hinweis: Wird normalerweise automatisch aufgerufen, manueller Aufruf nicht erforderlich.

Interne Logik:

cpp
void update(const Measurements& meas) {
    switch (mode) {
        case OFF:     processOffMode();           break;
        case AUTO:    processAutoMode(P_grid);    break;
        case ECO:     processEcoMode(P_grid);     break;
        case OFFGRID: processOffgridMode(meas);   break;
        case MANUAL:  processManualMode();        break;
        case BOOST:   processBoostMode();         break;
    }
}


Notabschaltung

emergencyStop()

cpp
void emergencyStop();

Beschreibung: Sofortige Dimmer-Abschaltung (0%) und Übergang in den OFF-Modus.

When to use:
- System overheating
- Sensor error
- Critical situation

Beispiel:

cpp
if (temperature > 80.0f) {
    router.emergencyStop();
    Serial.println("EMERGENCY STOP: Overheating!");
}


Status abrufen

getStatus()

cpp
RouterStatus getStatus() const;

Beschreibung: Vollständige Statusinformationen des Controllers abrufen.

Rückgabe: RouterStatus-Struktur

Beispiel:

cpp
RouterStatus status = router.getStatus();

Serial.printf("Mode: %d\n", static_cast(status.mode));
Serial.printf("State: %d\n", static_cast(status.state));
Serial.printf("Dimmer: %d%%\n", status.dimmer_percent);
Serial.printf("P_grid: %.1f W\n", status.power_grid);
Serial.printf("Kp: %.1f\n", status.control_gain);


Datenstrukturen

RouterStatus

cpp
struct RouterStatus {
    RouterMode mode;                    // Current mode
    RouterState state;                  // State (IDLE, INCREASING, etc.)
    uint8_t dimmer_percent;             // Dimmer level (0-100%)
    float target_level;                 // Target level (float for smoothness)
    float power_grid;                   // Current grid power (W)
    float control_gain;                 // Kp coefficient
    float balance_threshold;            // Balance threshold (W)
    uint32_t last_update_ms;            // Last update timestamp
    bool valid;                         // Status is valid
};

RouterMode

cpp
enum class RouterMode : uint8_t {
    OFF = 0,        // Disabled
    AUTO,           // Automatic Solar Router
    ECO,            // Economic (anti-export)
    OFFGRID,        // Autonomous
    MANUAL,         // Manual
    BOOST           // Forced 100%
};

RouterState

cpp
enum class RouterState : uint8_t {
    IDLE,           // No action
    INCREASING,     // Increasing dimmer (exporting)
    DECREASING,     // Decreasing dimmer (importing)
    AT_MAXIMUM,     // At maximum (100%)
    AT_MINIMUM,     // At minimum (0%)
    ERROR           // Error state
};



5.2 PowerMeterADC API

Dateien:
- components/acrouter_hal/include/PowerMeterADC.h
- components/acrouter_hal/src/PowerMeterADC.cpp

Entwurfsmuster: Singleton


Instanz abrufen

cpp
PowerMeterADC& powerMeter = PowerMeterADC::getInstance();


Initialisierung

begin()

cpp
bool begin();

Beschreibung: DMA-ADC initialisieren und FreeRTOS-Verarbeitungstask erstellen.

Rückgabe: true bei Erfolg

Beispiel:

cpp
PowerMeterADC& powerMeter = PowerMeterADC::getInstance();

if (powerMeter.begin()) {
    Serial.println("PowerMeterADC initialized");
} else {
    Serial.println("PowerMeterADC init failed");
}


Messsteuerung

start()

cpp
bool start();

Beschreibung: Kontinuierliche DMA-ADC-Messungen starten.

Rückgabe: true bei erfolgreichem Start

Beispiel:

cpp
if (powerMeter.start()) {
    Serial.println("Measurements started");
}

stop()

cpp
void stop();

Beschreibung: Messungen stoppen.

Beispiel:

cpp
powerMeter.stop();
Serial.println("Measurements stopped");

isRunning()

cpp
bool isRunning() const;

Beschreibung: Prüfen, ob Messungen laufen.

Rückgabe: true wenn Messungen aktiv sind



Ergebnis-Callback

setCallback()

cpp
void setCallback(std::function callback);

Beschreibung: Callback-Funktion setzen, die alle 200 ms mit RMS-Ergebnissen aufgerufen wird.

Parameters:
- callback - function of type void callback(const Measurements& meas)

Beispiel:

cpp
// Option 1: Lambda
powerMeter.setCallback([](const PowerMeterADC::Measurements& meas) {
    Serial.printf("V: %.1f V, I_grid: %.2f A, P_grid: %.1f W\n",
                  meas.voltage_rms,
                  meas.current_rms[PowerMeterADC::CURRENT_GRID],
                  meas.power_active[PowerMeterADC::CURRENT_GRID]);
});

// Option 2: Global function
void onMeasurements(const PowerMeterADC::Measurements& meas) {
    // Process measurements
}
powerMeter.setCallback(onMeasurements);

// Option 3: Class method
powerMeter.setCallback([this](const auto& meas) {
    this->handleMeasurements(meas);
});


Sensorkalibrierung

setVoltageCalibration()

cpp
void setVoltageCalibration(float multiplier, float offset = 0.0f);

Beschreibung: Kalibrierungskoeffizienten für den Spannungssensor festlegen.

Parameters:
- multiplier - multiplier (V/V_adc)
- offset - offset (V)

Formel: V_real = V_adc * multiplier + offset

Beispiel:

cpp
// ZMPT107: 230V � 1V (scale 1:230)
powerMeter.setVoltageCalibration(230.0f, 0.0f);

// With offset correction
powerMeter.setVoltageCalibration(235.0f, -2.5f);

setCurrentCalibration()

cpp
void setCurrentCalibration(CurrentChannel channel, float multiplier, float offset = 0.0f);

Beschreibung: Kalibrierungskoeffizienten für den Stromsensor festlegen.

Parameters:
- channel - channel (CURRENT_LOAD, CURRENT_GRID, CURRENT_SOLAR)
- multiplier - multiplier (A/V_adc)
- offset - offset (A)

Formel: I_real = I_adc * multiplier + offset

Beispiel:

cpp
// SCT-013-030: 30A � 1V
powerMeter.setCurrentCalibration(PowerMeterADC::CURRENT_GRID, 30.0f, 0.0f);

// ACS-712-20A: 0A=2.5V, sensitivity 100mV/A
powerMeter.setCurrentCalibration(PowerMeterADC::CURRENT_LOAD, 10.0f, -25.0f);


Daten abrufen

getPowerData()

cpp
Measurements getPowerData() const;

Beschreibung: Letzte Messungen abrufen (thread-sicher).

Rückgabe: Measurements-Struktur

Beispiel:

cpp
PowerMeterADC::Measurements data = powerMeter.getPowerData();

if (data.valid) {
    Serial.printf("Voltage: %.1f V\n", data.voltage_rms);
    Serial.printf("Current Grid: %.2f A\n", data.current_rms[PowerMeterADC::CURRENT_GRID]);
    Serial.printf("Power Grid: %.1f W\n", data.power_active[PowerMeterADC::CURRENT_GRID]);
}

getVoltageRMS()

cpp
float getVoltageRMS() const;

Beschreibung: Nur Spannungs-RMS abrufen.

Rückgabe: Spannung in Volt

getCurrentRMS()

cpp
float getCurrentRMS(CurrentChannel channel) const;

Beschreibung: RMS-Strom für den angegebenen Kanal abrufen.

Parameters:
- channel - CURRENT_LOAD, CURRENT_GRID or CURRENT_SOLAR

Rückgabe: Strom in Ampere

Beispiel:

cpp
float i_grid = powerMeter.getCurrentRMS(PowerMeterADC::CURRENT_GRID);
float i_solar = powerMeter.getCurrentRMS(PowerMeterADC::CURRENT_SOLAR);

Serial.printf("Grid: %.2f A, Solar: %.2f A\n", i_grid, i_solar);

getPower()

cpp
float getPower(CurrentChannel channel) const;

Beschreibung: Wirkleistung für den angegebenen Kanal abrufen.

Parameters:
- channel - CURRENT_LOAD, CURRENT_GRID or CURRENT_SOLAR

Rückgabe: Leistung in Watt

Beispiel:

cpp
float p_grid = powerMeter.getPower(PowerMeterADC::CURRENT_GRID);

if (p_grid < 0) {
    Serial.println("Exporting to grid");
} else {
    Serial.println("Importing from grid");
}


Datenstrukturen

Measurements

cpp
struct Measurements {
    float voltage_rms;                  // RMS voltage (V)
    float current_rms[3];               // RMS currents [LOAD, GRID, SOLAR] (A)
    float power_active[3];              // Active power [LOAD, GRID, SOLAR] (W)
    float power_reactive[3];            // Reactive power (VAR) - Phase 2
    float power_apparent[3];            // Apparent power (VA) - Phase 2
    float power_factor[3];              // Power factor - Phase 2
    uint32_t timestamp_ms;              // Timestamp
    bool valid;                         // Data is valid
};

CurrentChannel

cpp
enum CurrentChannel : uint8_t {
    CURRENT_LOAD = 0,    // Load current (dimmer)
    CURRENT_GRID = 1,    // Grid current (import/export)
    CURRENT_SOLAR = 2,   // Solar panel current
    CURRENT_COUNT = 3
};



5.3 DimmerHAL API

Dateien:
- components/acrouter_hal/include/DimmerHAL.h
- components/acrouter_hal/src/DimmerHAL.cpp

Entwurfsmuster: Singleton


Instanz abrufen

cpp
DimmerHAL& dimmer = DimmerHAL::getInstance();


Initialisierung

begin()

cpp
bool begin();

Beschreibung: Dimmer mit Nulldurchgangsdetektor initialisieren.

Rückgabe: true bei Erfolg

Beispiel:

cpp
DimmerHAL& dimmer = DimmerHAL::getInstance();

if (dimmer.begin()) {
    Serial.println("DimmerHAL initialized");
} else {
    Serial.println("DimmerHAL init failed");
}


Leistungssteuerung

setPower()

cpp
void setPower(DimmerChannel channel, uint8_t percent);

Beschreibung: Dimmer-Leistung sofort setzen.

Parameters:
- channel - CHANNEL_1 or CHANNEL_2
- percent - power 0-100%

Beispiel:

cpp
dimmer.setPower(DimmerChannel::CHANNEL_1, 75);  // 75%
dimmer.setPower(DimmerChannel::CHANNEL_2, 50);  // 50% on second channel

setPowerSmooth()

cpp
void setPowerSmooth(DimmerChannel channel, uint8_t percent, uint32_t transition_ms);

Beschreibung: Leistung mit sanftem Übergang setzen.

Parameters:
- channel - CHANNEL_1 or CHANNEL_2
- percent - target power 0-100%
- transition_ms - transition time in milliseconds

Beispiel:

cpp
// Smoothly transition to 80% over 2 seconds
dimmer.setPowerSmooth(DimmerChannel::CHANNEL_1, 80, 2000);

// Smooth shutdown over 1 second
dimmer.setPowerSmooth(DimmerChannel::CHANNEL_1, 0, 1000);

getPower()

cpp
uint8_t getPower(DimmerChannel channel) const;

Beschreibung: Aktuelle Kanalleistung abrufen.

Rückgabe: Leistung 0-100%

Beispiel:

cpp
uint8_t current_power = dimmer.getPower(DimmerChannel::CHANNEL_1);
Serial.printf("Dimmer 1: %d%%\n", current_power);


Schnellsteuerung

turnOff()

cpp
void turnOff(DimmerChannel channel);

Beschreibung: Kanal schnell abschalten (0%).

Beispiel:

cpp
dimmer.turnOff(DimmerChannel::CHANNEL_1);

turnOffAll()

cpp
void turnOffAll();

Beschreibung: Alle Kanäle abschalten.

Beispiel:

cpp
dimmer.turnOffAll();  // Emergency shutdown


Leistungskurve

setCurve()

cpp
void setCurve(DimmerChannel channel, DimmerCurve curve);

Beschreibung: Typ der Leistungskurve festlegen.

Parameters:
- channel - CHANNEL_1 or CHANNEL_2
- curve - LINEAR, RMS or LOGARITHMIC

Recommendations:
- RMS - for resistive loads (heaters, water heaters) - recommended
- LINEAR - linear dependency
- LOGARITHMIC - for LED lamps

Beispiel:

cpp
// RMS curve for heater (recommended)
dimmer.setCurve(DimmerChannel::CHANNEL_1, DimmerCurve::RMS);

// Linear curve
dimmer.setCurve(DimmerChannel::CHANNEL_1, DimmerCurve::LINEAR);


Status und Information

getStatus()

cpp
DimmerStatus getStatus(DimmerChannel channel) const;

Beschreibung: Detaillierten Kanalstatus abrufen.

Rückgabe: DimmerStatus-Struktur

Beispiel:

cpp
DimmerStatus status = dimmer.getStatus(DimmerChannel::CHANNEL_1);

Serial.printf("Initialized: %s\n", status.initialized ? "Yes" : "No");
Serial.printf("Active: %s\n", status.active ? "Yes" : "No");
Serial.printf("Power: %d%%\n", status.power_percent);
Serial.printf("Target: %d%%\n", status.target_percent);

isInitialized()

cpp
bool isInitialized() const;

Beschreibung: Prüfen, ob der Dimmer initialisiert ist.

Rückgabe: true wenn initialisiert



Datenstrukturen

DimmerChannel

cpp
enum class DimmerChannel : uint8_t {
    CHANNEL_1 = 0,      // First channel (GPIO 19)
    CHANNEL_2 = 1       // Second channel (GPIO 23)
};

DimmerCurve

cpp
enum class DimmerCurve : uint8_t {
    LINEAR,         // Linear
    RMS,            // RMS-compensated (recommended)
    LOGARITHMIC     // Logarithmic
};

DimmerStatus

cpp
struct DimmerStatus {
    bool initialized;           // Initialized
    bool active;                // Active
    uint8_t power_percent;      // Current power (0-100%)
    uint8_t target_percent;     // Target power (during transition)
    DimmerCurve curve;          // Curve type
    uint32_t last_update_ms;    // Last update time
};



5.4 ConfigManager API

Dateien:
- components/utils/include/ConfigManager.h
- components/utils/src/ConfigManager.cpp

Entwurfsmuster: Singleton

NVS-Namespace: "acrouter"


Instanz abrufen

cpp
ConfigManager& config = ConfigManager::getInstance();


Initialisierung

begin()

cpp
bool begin();

Beschreibung: NVS initialisieren und Konfiguration laden.

Rückgabe: true bei Erfolg

Beispiel:

cpp
ConfigManager& config = ConfigManager::getInstance();

if (config.begin()) {
    Serial.println("ConfigManager initialized");
    Serial.printf("Router mode: %d\n", config.getConfig().router_mode);
}


Konfiguration abrufen

getConfig()

cpp
const SystemConfig& getConfig() const;

Beschreibung: Referenz auf aktuelle Konfiguration abrufen.

Rückgabe: Const-Referenz auf SystemConfig

Beispiel:

cpp
const SystemConfig& cfg = config.getConfig();

Serial.printf("Mode: %d\n", cfg.router_mode);
Serial.printf("Kp: %.1f\n", cfg.control_gain);
Serial.printf("Threshold: %.1f W\n", cfg.balance_threshold);


Parameter setzen

setRouterMode()

cpp
bool setRouterMode(uint8_t mode);

Beschreibung: Router-Modus setzen (wird automatisch in NVS gespeichert).

Parameters:
- mode - mode 0-5

Rückgabe: true bei erfolgreichem Speichern

Beispiel:

cpp
config.setRouterMode(1);  // AUTO mode

setControlGain()

cpp
bool setControlGain(float gain);

Beschreibung: Kp-Koeffizient setzen.

Parameters:
- gain - coefficient (10.0 - 1000.0)

Beispiel:

cpp
config.setControlGain(200.0f);

setBalanceThreshold()

cpp
bool setBalanceThreshold(float threshold);

Beschreibung: Gleichgewichtsschwelle setzen.

Parameters:
- threshold - threshold in Watts (0.0 - 100.0)

Beispiel:

cpp
config.setBalanceThreshold(10.0f);

setManualLevel()

cpp
bool setManualLevel(uint8_t level);

Beschreibung: Stufe für den MANUAL-Modus setzen.

Parameters:
- level - level 0-100%

Beispiel:

cpp
config.setManualLevel(75);

setVoltageCoefficient()

cpp
bool setVoltageCoefficient(float coef);

Beschreibung: Spannungs-Kalibrierungskoeffizienten setzen.

Beispiel:

cpp
config.setVoltageCoefficient(230.0f);

setCurrentCoefficient()

cpp
bool setCurrentCoefficient(float coef);

Beschreibung: Strom-Kalibrierungskoeffizienten setzen.

Beispiel:

cpp
config.setCurrentCoefficient(30.0f);  // SCT-013-030


Stapeloperationen

saveAll()

cpp
bool saveAll();

Beschreibung: Alle Parameter in NVS speichern.

Hinweis: In der Regel nicht erforderlich, da jede set*()-Methode automatisch speichert.

loadAll()

cpp
bool loadAll();

Beschreibung: Konfiguration aus NVS neu laden.

resetToDefaults()

cpp
bool resetToDefaults();

Beschreibung: Alle Einstellungen auf Werkseinstellungen zurücksetzen und in NVS speichern.

Beispiel:

cpp
if (config.resetToDefaults()) {
    Serial.println("Config reset to defaults");
}


Datenstrukturen

SystemConfig

cpp
struct SystemConfig {
    // Router parameters
    uint8_t router_mode;        // RouterMode (0-5)
    float control_gain;         // Kp (10.0 - 1000.0)
    float balance_threshold;    // Balance threshold (W)
    uint8_t manual_level;       // MANUAL level (0-100%)

    // Sensor calibration
    float voltage_coef;         // Voltage coefficient
    float current_coef;         // Current coefficient (A/V)
    float current_threshold;    // Minimum current (A)
    float power_threshold;      // Minimum power (W)
};



5.5 HardwareConfigManager API

Dateien:
- components/utils/include/HardwareConfigManager.h
- components/utils/src/HardwareConfigManager.cpp

Entwurfsmuster: Singleton

NVS-Namespace: "hw_config"


Instanz abrufen

cpp
HardwareConfigManager& hwConfig = HardwareConfigManager::getInstance();


Initialisierung

begin()

cpp
bool begin();

Beschreibung: Hardware-Konfiguration aus NVS initialisieren und laden.

Beispiel:

cpp
HardwareConfigManager& hwConfig = HardwareConfigManager::getInstance();

if (hwConfig.begin()) {
    Serial.println("HardwareConfigManager initialized");
}


ADC-Kanal-Konfiguration

setADCChannel()

cpp
bool setADCChannel(uint8_t channel, const ADCChannelConfig& config);

Beschreibung: ADC-Kanal konfigurieren.

Parameters:
- channel - channel number (0-3)
- config - channel configuration

Rückgabe: true bei Erfolg

Beispiel:

cpp
ADCChannelConfig voltage_cfg;
voltage_cfg.gpio = 35;
voltage_cfg.type = SensorType::VOLTAGE_AC;
voltage_cfg.multiplier = 230.0f;
voltage_cfg.offset = 0.0f;
voltage_cfg.enabled = true;

hwConfig.setADCChannel(0, voltage_cfg);

getADCChannel()

cpp
ADCChannelConfig getADCChannel(uint8_t channel) const;

Beschreibung: ADC-Kanal-Konfiguration abrufen.

Beispiel:

cpp
ADCChannelConfig cfg = hwConfig.getADCChannel(0);
Serial.printf("ADC0: GPIO%d, Type=%d, Mult=%.1f\n",
              cfg.gpio, static_cast(cfg.type), cfg.multiplier);


Dimmer-Konfiguration

setDimmerChannel()

cpp
bool setDimmerChannel(uint8_t channel, const DimmerChannelConfig& config);

Beschreibung: Dimmer-Kanal konfigurieren.

Parameters:
- channel - 0 (Channel 1) or 1 (Channel 2)
- config - configuration

Beispiel:

cpp
DimmerChannelConfig dim_cfg;
dim_cfg.gpio = 19;
dim_cfg.enabled = true;

hwConfig.setDimmerChannel(0, dim_cfg);


Nulldurchgangs-Konfiguration

setZeroCross()

cpp
bool setZeroCross(uint8_t gpio, bool enabled = true);

Beschreibung: GPIO-Pin für Nulldurchgangsdetektor konfigurieren.

Beispiel:

cpp
hwConfig.setZeroCross(18, true);  // GPIO18, enabled


Relais-Konfiguration

setRelayChannel()

cpp
bool setRelayChannel(uint8_t channel, const RelayChannelConfig& config);

Beschreibung: Relais-Kanal konfigurieren.

Parameters:
- channel - 0 or 1
- config - relay configuration

Beispiel:

cpp
RelayChannelConfig relay_cfg;
relay_cfg.gpio = 15;
relay_cfg.active_high = true;  // Active HIGH
relay_cfg.enabled = true;

hwConfig.setRelayChannel(0, relay_cfg);


LED-Konfiguration

setStatusLED()

cpp
bool setStatusLED(uint8_t gpio);

Beschreibung: GPIO für Status-LED konfigurieren.

Beispiel:

cpp
hwConfig.setStatusLED(17);

setLoadLED()

cpp
bool setLoadLED(uint8_t gpio);

Beschreibung: GPIO für Last-Anzeige-LED konfigurieren.



Validierung

validate()

cpp
bool validate(String* error_msg = nullptr) const;

Beschreibung: Konfiguration auf Fehler prüfen.

Parameters:
- error_msg - pointer to String for error message (optional)

Rückgabe: true wenn Konfiguration gültig ist

Checks:
- GPIO conflicts (one pin = one function)
- Pin validity for ADC (ADC1 only: 32-39)
- Input-only pins (34,35,36,39 cannot be outputs)

Beispiel:

cpp
String error;
if (!hwConfig.validate(&error)) {
    Serial.printf("Validation failed: %s\n", error.c_str());
} else {
    Serial.println("Configuration is valid");
}


Stapeloperationen

saveAll()

cpp
bool saveAll();

Beschreibung: Gesamte Konfiguration in NVS speichern.

loadAll()

cpp
bool loadAll();

Beschreibung: Konfiguration aus NVS laden.

resetToDefaults()

cpp
bool resetToDefaults();

Beschreibung: Auf Werkseinstellungen zurücksetzen.

printConfig()

cpp
void printConfig() const;

Beschreibung: Konfiguration über Serial ausgeben.

Beispiel:

cpp
hwConfig.printConfig();
// Output:
// === Hardware Configuration ===
// ADC0: GPIO35, VOLTAGE_AC, mult=230.0, enabled
// ADC1: GPIO39, CURRENT_LOAD, mult=30.0, enabled
// ...


Datenstrukturen

ADCChannelConfig

cpp
struct ADCChannelConfig {
    uint8_t gpio;               // GPIO pin (32-39 for ADC1)
    SensorType type;            // Sensor type
    float multiplier;           // Calibration multiplier
    float offset;               // Offset
    bool enabled;               // Channel enabled
};

DimmerChannelConfig

cpp
struct DimmerChannelConfig {
    uint8_t gpio;               // GPIO pin
    bool enabled;               // Channel enabled
};

RelayChannelConfig

cpp
struct RelayChannelConfig {
    uint8_t gpio;               // GPIO pin
    bool active_high;           // true=Active HIGH, false=Active LOW
    bool enabled;               // Channel enabled
};

SensorType

cpp
enum class SensorType : uint8_t {
    NONE = 0,           // Not used
    VOLTAGE_AC,         // ZMPT107 (AC voltage)
    CURRENT_LOAD,       // ACS-712 (dimmer load current)
    CURRENT_GRID,       // SCT-013 (grid current)
    CURRENT_SOLAR,      // SCT-013 (solar current)
    CURRENT_AUX1,       // Auxiliary channel 1
    CURRENT_AUX2        // Auxiliary channel 2
};



5.6 WiFiManager API

Dateien:
- components/comm/include/WiFiManager.h
- components/comm/src/WiFiManager.cpp

Entwurfsmuster: Singleton


Instanz abrufen

cpp
WiFiManager& wifi = WiFiManager::getInstance();


Initialisierung

begin()

cpp
bool begin();

Beschreibung: WiFi initialisieren. Startet automatisch AP, wenn keine STA-Zugangsdaten vorhanden.

Rückgabe: true bei Erfolg

Beispiel:

cpp
WiFiManager& wifi = WiFiManager::getInstance();

if (wifi.begin()) {
    Serial.println("WiFiManager initialized");

    WiFiStatus status = wifi.getStatus();
    Serial.printf("AP IP: %s\n", status.ap_ip.toString().c_str());
}


AP-Modus

startAP()

cpp
bool startAP(const char* ssid = nullptr, const char* password = nullptr);

Beschreibung: Access Point starten.

Parameters:
- ssid - network SSID (nullptr = auto: "ACRouter_XXXXXX")
- password - password (nullptr = "12345678")

Beispiel:

cpp
// With auto-generated SSID
wifi.startAP();

// With custom SSID
wifi.startAP("MyACRouter", "mypassword123");

stopAP()

cpp
void stopAP();

Beschreibung: Access Point stoppen.

isAPActive()

cpp
bool isAPActive() const;

Rückgabe: true wenn AP aktiv ist



STA-Modus

connectSTA()

cpp
bool connectSTA(const char* ssid, const char* password);

Beschreibung: Mit WiFi-Netzwerk verbinden.

Parameters:
- ssid - network SSID
- password - password

Rückgabe: true wenn verbunden

Beispiel:

cpp
if (wifi.connectSTA("HomeNetwork", "password123")) {
    Serial.println("Connected to WiFi");

    WiFiStatus status = wifi.getStatus();
    Serial.printf("STA IP: %s\n", status.sta_ip.toString().c_str());
}

disconnectSTA()

cpp
void disconnectSTA();

Beschreibung: Vom STA-Netzwerk trennen.

isSTAConnected()

cpp
bool isSTAConnected() const;

Rückgabe: true wenn mit STA verbunden



Netzwerk-Scan

scanNetworks()

cpp
std::vector scanNetworks();

Beschreibung: Verfügbare WiFi-Netzwerke scannen.

Rückgabe: Vektor von WiFiNetwork-Strukturen

Beispiel:

cpp
std::vector networks = wifi.scanNetworks();

Serial.printf("Found %d networks:\n", networks.size());
for (const auto& net : networks) {
    Serial.printf("  %s (RSSI: %d, Encrypted: %s)\n",
                  net.ssid.c_str(),
                  net.rssi,
                  net.encrypted ? "Yes" : "No");
}


Status

getStatus()

cpp
WiFiStatus getStatus() const;

Beschreibung: Vollständigen WiFi-Status abrufen.

Beispiel:

cpp
WiFiStatus status = wifi.getStatus();

Serial.printf("State: %d\n", static_cast(status.state));
Serial.printf("STA connected: %s\n", status.sta_connected ? "Yes" : "No");
Serial.printf("AP active: %s\n", status.ap_active ? "Yes" : "No");

if (status.sta_connected) {
    Serial.printf("STA IP: %s\n", status.sta_ip.toString().c_str());
    Serial.printf("RSSI: %d dBm\n", status.rssi);
}

if (status.ap_active) {
    Serial.printf("AP IP: %s\n", status.ap_ip.toString().c_str());
    Serial.printf("Clients: %d\n", status.sta_clients);
}


Datenstrukturen

WiFiState

cpp
enum class WiFiState : uint8_t {
    IDLE,               // Not initialized
    AP_ONLY,            // AP only
    STA_CONNECTING,     // Connecting to STA
    STA_CONNECTED,      // Connected to STA
    AP_STA,             // Both modes
    STA_FAILED          // STA failed
};

WiFiStatus

cpp
struct WiFiStatus {
    WiFiState state;
    bool sta_connected;
    bool ap_active;
    IPAddress sta_ip;
    IPAddress ap_ip;
    String sta_ssid;
    String ap_ssid;
    int8_t rssi;
    uint8_t sta_clients;        // Clients on AP
};

WiFiNetwork

cpp
struct WiFiNetwork {
    String ssid;
    int8_t rssi;
    bool encrypted;
};



5.7 WebServerManager API

Dateien:
- components/comm/include/WebServerManager.h
- components/comm/src/WebServerManager.cpp

Entwurfsmuster: Singleton


Instanz abrufen

cpp
WebServerManager& webServer = WebServerManager::getInstance();


Initialisierung

begin()

cpp
bool begin(uint16_t http_port = 80);

Beschreibung: HTTP-Server initialisieren.

Parameters:
- http_port - HTTP port (default 80)

Beispiel:

cpp
WebServerManager& webServer = WebServerManager::getInstance();

if (webServer.begin(80)) {
    Serial.println("WebServer started on port 80");
}


Steuerung

start()

cpp
void start();

Beschreibung: Webserver starten.

stop()

cpp
void stop();

Beschreibung: Webserver stoppen.

isRunning()

cpp
bool isRunning() const;

Rückgabe: true wenn Server läuft



Anfrageverarbeitung

handleClient()

cpp
void handleClient();

Beschreibung: Eingehende HTTP-Anfragen verarbeiten. Aus loop() aufrufen.

Beispiel:

cpp
void loop() {
    webServer.handleClient();
    // ... rest of code
}


REST API-Endpunkte

Die vollständige Endpunktliste finden Sie in Abschnitt 8: GET-Endpunkte und Abschnitt 9: POST-Endpunkte.

Hauptgruppen:

  • Webseiten: /, /wifi, /settings/hardware
  • Status: /api/status, /api/metrics, /api/config
  • Steuerung: /api/mode, /api/manual, /api/calibrate
  • WiFi: /api/wifi/*
  • Hardware: /api/hardware/*
  • System: /api/system/reboot

← Router-Modi | Inhaltsverzeichnis | Weiter: Hauptanwendung →