Se rendre au contenu

← Structure de l'application | Sommaire | Suivant : Référence API →

4. Modes de fonctionnement du RouterController



4.1 Vue d'ensemble des modes

Le RouterController prend en charge 6 modes de fonctionnement, chacun optimisé pour un scénario d'utilisation spécifique.


Tableau des modes

Mode Enum Contrôle variateur Contrôle P_grid Capteurs requis Application
OFF 0 0% (fixe) ❌ Non - Maintenance, arrêt
AUTO 1 Automatique ✅ P_grid → 0 Courant réseau Routeur solaire standard
ECO 2 Semi-automatique ⚠️ Import uniquement Courant réseau Prévention d'export
OFFGRID 3 Automatique ❌ Non Courant solaire Systèmes autonomes
MANUAL 4 Fixe ❌ Non - Tarif de nuit, test
BOOST 5 100% (fixe) ❌ Non - Chauffage forcé



4.2 Mode OFF (0) – Désactivé


Description

Arrêt complet du contrôle du variateur. Utilisé pour la maintenance, le débogage ou lorsque le contrôle de la charge n'est pas nécessaire.


Algorithme

cpp
void RouterController::processOffMode() {
    // Dimmer always 0%
    if (m_status.dimmer_percent != 0) {
        applyDimmerLevel(0);
    }
    m_status.state = RouterState::IDLE;
}


Paramètres

Aucun paramètre configurable.


Capteurs requis

Les capteurs ne sont pas nécessaires (les mesures continuent mais ne sont pas utilisées).


Comportement

  • Niveau du variateur : 0% (constant)
  • P_grid : Non contrôlé
  • État : IDLE
  • Mesures : Continuent (PowerMeterADC fonctionne)
  • Interface web : Disponible
  • Commandes série : Fonctionnelles


Quand utiliser

  • ✅ Maintenance de l'appareil
  • ✅ Test des capteurs sans contrôle
  • ✅ Débogage du système
  • ✅ Déconnexion temporaire de la charge


Exemple d'utilisation

cpp
// Via code
RouterController& router = RouterController::getInstance();
router.setMode(RouterMode::OFF);

// Via Serial
set-mode 0

// Via REST API
POST /api/mode
{"mode": 0}



4.3 Mode AUTO (1) – Routeur solaire automatique


Description

Mode principal du routeur solaire. Équilibre automatiquement la puissance réseau (P_grid) à zéro, en redirigeant l'excédent d'énergie solaire vers la charge au lieu de l'exporter vers le réseau.


Algorithme

cpp
void RouterController::processAutoMode(float power_grid) {
    // Goal: P_grid → 0
    // Proportional control with configurable gain

    float error = -power_grid;  // Invert: export = positive error

    // Check if within balance threshold
    if (fabs(power_grid) <= balance_threshold) {
        // Within threshold - hold current level
        return;
    }

    // Proportional control
    float delta = error / control_gain;
    m_target_level += delta;

    // Apply new level (clamped to 0-100%)
    applyDimmerLevel(m_target_level);
}


Comportement selon le signe de P_grid

Situation P_grid Erreur Delta Action
Export vers le réseau < 0 (négatif) > 0 (positif) > 0 Augmenter le variateur → plus de charge
Import depuis le réseau > 0 (positif) < 0 (négatif) < 0 Diminuer le variateur → moins de charge
Équilibre ≈ 0 (dans le seuil) ≈ 0 0 Maintenir le niveau actuel


Paramètres

control_gain (Kp)

Description : Coefficient du régulateur proportionnel. Détermine la vitesse de réaction aux variations de P_grid.

Formule : delta = error / control_gain

Plage : 10.0 - 1000.0

Défaut : 200.0

Impact :

  • Kp inférieur (plus rapide) :
  • ✅ Réaction rapide aux changements
  • ❌ Oscillations possibles
  • Exemple : Kp = 50 → rapide, mais instable

  • Kp supérieur (plus lent) :

  • ✅ Contrôle en douceur
  • ✅ Stabilité
  • ❌ Réaction lente
  • Exemple : Kp = 500 → lent, mais stable

Recommandations :

python
System Type              | Recommended Kp | Comment
-------------------------|----------------|------------------------
Stable grid              | 150 - 250      | Optimal
Unstable grid            | 300 - 500      | Increase for stability
Fast clouds              | 100 - 150      | Decrease for responsiveness
High inertia heater      | 200 - 400      | Medium values

balance_threshold

Description : Seuil d'équilibre en Watts. Si |P_grid| < seuil, le système est considéré comme équilibré.

Plage : 0.0 - 100.0 W

Défaut : 10.0 W

Impact :

  • Seuil inférieur :
  • ✅ Équilibre plus précis (P_grid plus proche de 0)
  • ❌ Plus d'ajustements (usure du TRIAC)

  • Seuil supérieur :

  • ✅ Moins de cycles de commutation
  • ❌ Équilibre moins précis

Recommandations :

python
Load Power               | Recommended Threshold
-------------------------|----------------------
< 500 W                  | 5 - 10 W
500 - 1500 W             | 10 - 20 W
> 1500 W                 | 20 - 50 W


Capteurs requis

Minimum :

  • Current Grid (requis) – pour la détermination de P_grid
  • Voltage (recommandé) – pour le calcul de puissance

Optionnel :

  • ⚪ Current Load – pour la surveillance de la consommation
  • ⚪ Current Solar – pour la surveillance de la production


Exemples de fonctionnement

Exemple 1 : Excédent solaire

python
Initial state:
  P_solar = 3000 W
  P_house = 800 W
  P_grid = -2200 W (export!)
  Dimmer = 0%

After 10 seconds (Kp=200):
  error = -(-2200) = +2200
  delta = 2200 / 200 = +11% per iteration
  → Dimmer gradually increases

After 30 seconds:
  Dimmer ≈ 70% (~1400 W to heater)
  P_grid ≈ -800 W (still exporting)
  → Continues to increase

After 60 seconds (stabilization):
  Dimmer = 95% (~1900 W)
  P_grid ≈ -5 W (within 10W threshold)
  → Balance achieved ✅

Exemple 2 : Un nuage cache le soleil

python
Stable state:
  P_solar = 2500 W
  P_grid = 0 W (balance)
  Dimmer = 80% (~1600 W)

Cloud:
  P_solar = 500 W (sharp drop)
  P_grid = +1100 W (import!)

  error = -1100
  delta = -1100 / 200 = -5.5%
  → Dimmer decreases by 5.5%

After 5 seconds:
  Dimmer ≈ 50% (~1000 W)
  P_grid ≈ +100 W (close to balance)

After 10 seconds:
  Dimmer = 30% (~600 W)
  P_grid ≈ +5 W (within threshold)
  → New balance achieved ✅


Configuration via les interfaces

cpp
// Via code
router.setMode(RouterMode::AUTO);
router.setControlGain(200.0f);
router.setBalanceThreshold(10.0f);

// Via Serial
set-mode 1
set-kp 200
set-threshold 10

// Via REST API
POST /api/mode
{"mode": 1}

POST /api/config
{"control_gain": 200.0, "balance_threshold": 10.0}



4.4 Mode ECO (2) – Économie (Anti-Export)


Description

Mode de prévention d'export. Évite l'injection d'électricité vers le réseau, mais autorise l'import. Utilisé lorsque l'export est non rentable ou interdit.


Algorithme

cpp
void RouterController::processEcoMode(float power_grid) {
    // Goal: P_grid >= 0 (avoid export, allow import)

    if (power_grid > balance_threshold) {
        // IMPORTING from grid - reduce load
        float error = -power_grid;

        // Slower response: increase gain by 1.5x
        float delta = error / (control_gain * 1.5f);
        m_target_level += delta;

        applyDimmerLevel(m_target_level);
    } else {
        // EXPORTING or BALANCED - hold current level
        // Do not increase load aggressively
    }
}


Différences avec AUTO

Aspect AUTO ECO
Export Empêché (variateur augmente) Autorisé (variateur n'augmente pas)
Import Empêché (variateur diminue) Autorisé (variateur diminue lentement)
Vitesse de réaction Rapide (Kp) Plus lente (Kp × 1,5)
Objectif P_grid = 0 P_grid ≥ 0


Comportement

  • P_grid > seuil (import) :
  • Diminuer lentement le variateur
  • Vitesse : Kp × 1,5 (plus lent qu'AUTO)

  • P_grid < 0 (export) :

  • NE PAS augmenter le variateur
  • Maintenir le niveau actuel

  • P_grid ≈ 0 :

  • Maintenir le niveau actuel


Paramètres

Identiques à AUTO :

  • control_gain – affecte la vitesse de diminution lors de l'import
  • balance_threshold – seuil de détermination de l'équilibre


Capteurs requis

  • Current Grid (requis)
  • Voltage (recommandé)


Quand utiliser

  • ✅ Pas de contrat d'export vers le réseau
  • ✅ Tarif d'export défavorable (< coût d'import)
  • ✅ Restriction technique d'export
  • ✅ Protection contre l'export avec réseau instable


Exemple de fonctionnement

python
Initial state:
  P_solar = 2000 W
  P_house = 1000 W
  P_grid = -1000 W (export 1 kW)
  Dimmer = 0%

In ECO mode:
  → Dimmer does NOT increase
  → P_grid remains -1000 W (export continues)

  Result: Excess goes to grid (acceptable in ECO)

After 1 hour (cloud):
  P_solar = 500 W
  P_house = 1000 W
  P_grid = +500 W (import!)

  → Dimmer slowly decreases (if it was enabled)
  → After some time P_grid ≈ 0



4.5 Mode OFFGRID (3) – Autonome


Description

Mode pour systèmes autonomes avec panneaux solaires et batteries, sans raccordement au réseau. Utilise l'excédent d'énergie solaire pour alimenter la charge.


Algorithme

cpp
void RouterController::processOffgridMode(const Measurements& meas) {
    float power_solar = meas.power_active[CURRENT_SOLAR];
    float power_load = meas.power_active[CURRENT_LOAD];

    if (power_solar > balance_threshold) {
        // Solar generation available
        float available_power = power_solar * 0.8f;  // 80% safety margin

        if (available_power > power_load + balance_threshold) {
            // Can increase load
            float delta = (available_power - power_load) / (control_gain * 2.0f);
            m_target_level += delta;
        } else if (available_power < power_load - balance_threshold) {
            // Need to reduce load
            m_target_level -= 5.0f;  // Gradual decrease
        }

        applyDimmerLevel(m_target_level);
    } else {
        // No solar generation - reduce load to minimum
        m_target_level -= 10.0f;  // Faster decrease
        applyDimmerLevel(m_target_level);
    }
}


Particularités

  • N'utilise PAS P_grid (le capteur réseau peut être absent)
  • Utilise P_solar pour déterminer la puissance disponible
  • Conservateur : 80% de la puissance disponible (protection de la batterie)
  • Priorité : Charge principale → Batteries → Chauffage


Paramètres

  • control_gain – affecte la vitesse d'augmentation de la charge
  • balance_threshold – puissance solaire minimale pour l'activation
  • Marge de sécurité : 0,8 (80%) – codée en dur


Capteurs requis

Minimum :

  • Current Solar (requis) – pour la détermination de la production
  • Voltage (recommandé)

Optionnel :

  • ⚪ Current Load – pour un contrôle plus précis
  • ❌ Current Grid – NON requis (peut être absent)


Quand utiliser

  • ✅ Systèmes autonomes
  • ✅ Panneaux solaires + batteries
  • ✅ Pas de raccordement au réseau
  • ✅ Maximiser l'utilisation de l'énergie solaire


Exemple de fonctionnement

python
Daytime (sunny):
  P_solar = 1500 W
  P_house = 800 W (from battery/solar)
  P_load (dimmer) = 0 W

  available_power = 1500 * 0.8 = 1200 W

  → Can turn on heater
  → Dimmer gradually increases to ~60% (1200 W)
  → Battery is not discharging (enough solar)

Evening (sunset):
  P_solar = 200 W (dropping)
  available_power = 200 * 0.8 = 160 W
  P_load = 800 W (heater was on)

  → Too little solar
  → Dimmer quickly decreases (10% per iteration)
  → After several iterations: Dimmer = 0%
  → Battery is saved for main load

Night:
  P_solar = 0 W
  → Dimmer = 0%
  → Heater is off



4.6 Mode MANUAL (4) – Manuel


Description

Niveau fixe du variateur défini par l'utilisateur. Pas de contrôle automatique.


Algorithme

cpp
void RouterController::processManualMode() {
    // Fixed level set by user
    if (m_status.dimmer_percent != m_manual_level) {
        applyDimmerLevel(m_manual_level);
    }
    m_status.state = RouterState::IDLE;
}


Paramètres

  • manual_level – niveau du variateur (0-100%)


Capteurs requis

Les capteurs ne sont pas nécessaires (les mesures continuent pour la surveillance).


Quand utiliser

  • ✅ Tarif de nuit (régler à 100% pour la nuit)
  • ✅ Test de charge
  • ✅ Maintien de température (régler à 50%)
  • ✅ Débogage du système


Exemple d'utilisation

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

// Via Serial
set-mode 4
set-manual 75

// Via REST API
POST /api/mode
{"mode": 4}

POST /api/manual
{"level": 75}


Scénario : Tarif de nuit

bash
# 23:00 - night tariff starts (cheap)
set-mode 4
set-manual 100  # Full power

# 07:00 - night tariff ends
set-mode 1      # Switch to AUTO



4.7 Mode BOOST (5) – Chauffage forcé


Description

Variateur fixé à 100%. Puissance maximale vers la charge.


Algorithme

cpp
void RouterController::processBoostMode() {
    // Always 100%
    if (m_status.dimmer_percent != 100) {
        applyDimmerLevel(100);
    }
    m_status.state = RouterState::AT_MAXIMUM;
}


Paramètres

Aucun paramètre configurable (toujours 100%).


Capteurs requis

Non requis.


Quand utiliser

  • ✅ Chauffage rapide du chauffe-eau
  • ✅ Utilisation d'un tarif avantageux
  • ✅ Mode d'urgence


Avertissements

⚠️ AVERTISSEMENT :

  • Consommation réseau élevée
  • Risque de surchauffe de la charge
  • Surveiller la température manuellement
  • Ne pas laisser sans surveillance


Exemple d'utilisation

cpp
// Enable BOOST
router.setMode(RouterMode::BOOST);

// Return to AUTO after 2 hours
delay(2 * 60 * 60 * 1000);
router.setMode(RouterMode::AUTO);



4.8 Passage d'un mode à l'autre


Transition sécurisée

Lors d'un changement de mode, le RouterController :

  1. Enregistre le changement de mode
  2. Réinitialise l'état interne
  3. Applique le nouvel algorithme
cpp
void RouterController::setMode(RouterMode mode) {
    if (m_status.mode == mode) {
        return;  // No change
    }

    RouterMode old_mode = m_status.mode;
    m_status.mode = mode;

    ESP_LOGI(TAG, "Mode changed: %d -> %d",
             static_cast(old_mode),
             static_cast(mode));

    // Reset state for new mode
    m_status.state = RouterState::IDLE;
}


Recommandations pour les transitions

Transitions sûres :

python
OFF ↔ AUTO      ✅ Safe
OFF ↔ MANUAL    ✅ Safe
AUTO ↔ ECO      ✅ Safe (similar algorithms)
MANUAL ↔ BOOST  ✅ Safe

Précaution :

python
AUTO → BOOST    ⚠️ Sharp power spike
OFFGRID → AUTO  ⚠️ Different sensors


Séquences de commandes

bash
# Example 1: Morning transition
set-mode 0        # OFF - pause
# ... system check ...
set-mode 1        # AUTO - start operation

# Example 2: Testing
set-mode 4        # MANUAL
set-manual 25     # 25% for test
# ... observation ...
set-manual 50     # 50%
# ... observation ...
set-mode 1        # Return to AUTO



4.9 Configurations minimales de capteurs


Pour chaque mode

Mode Capteurs requis Optionnel Remarque
OFF - - Capteurs non utilisés
AUTO Voltage, Current Grid Current Load, Current Solar Grid nécessaire pour P_grid
ECO Voltage, Current Grid Current Load, Current Solar Grid nécessaire pour P_grid
OFFGRID Voltage, Current Solar Current Load Grid NON requis
MANUAL - Voltage, Current Grid Pour la surveillance uniquement
BOOST - Voltage, Current Grid Pour la surveillance uniquement


Configuration minimale (routeur solaire)

Pour les modes AUTO/ECO :

python
ADC0: GPIO35, VOLTAGE_AC,    enabled=true   ← Required
ADC1: GPIO36, CURRENT_GRID,  enabled=true   ← Required
ADC2: -,      NONE,           enabled=false
ADC3: -,      NONE,           enabled=false

Dimmer1: GPIO19, enabled=true               ← Required
ZeroCross: GPIO18, enabled=true             ← Required

Résultat :

  • ✅ Mesure de P_grid (pour l'équilibre)
  • ✅ Contrôle du variateur
  • ❌ Pas de surveillance solaire/charge


Configuration complète

python
ADC0: GPIO35, VOLTAGE_AC,     enabled=true
ADC1: GPIO39, CURRENT_LOAD,   enabled=true
ADC2: GPIO36, CURRENT_GRID,   enabled=true
ADC3: GPIO34, CURRENT_SOLAR,  enabled=true

Dimmer1: GPIO19, enabled=true
Dimmer2: GPIO23, enabled=true (optional)
ZeroCross: GPIO18, enabled=true

Résultat :

  • ✅ Surveillance complète du système
  • ✅ Tous les modes pris en charge
  • ✅ Analyses détaillées



4.10 Configuration des paramètres via les interfaces


Par commandes série

bash
# Mode switching
set-mode 0          # OFF
set-mode 1          # AUTO
set-mode 2          # ECO
set-mode 3          # OFFGRID
set-mode 4          # MANUAL
set-mode 5          # BOOST

# AUTO/ECO parameters
set-kp 200          # Set Kp = 200
set-threshold 10    # Balance threshold 10 W

# MANUAL parameters
set-manual 75       # Set 75%

# Save
config-save         # Save to NVS


Par REST API

bash
# Set mode
curl -X POST http://192.168.4.1/api/mode \
  -H "Content-Type: application/json" \
  -d '{"mode": 1}'

# Set parameters
curl -X POST http://192.168.4.1/api/config \
  -H "Content-Type: application/json" \
  -d '{
    "control_gain": 200.0,
    "balance_threshold": 10.0
  }'

# Set MANUAL level
curl -X POST http://192.168.4.1/api/manual \
  -H "Content-Type: application/json" \
  -d '{"level": 75}'


Par interface web

  1. Ouvrir le tableau de bord : http://192.168.4.1/
  2. Sélectionner le mode (6 boutons)
  3. Pour MANUAL : déplacer le curseur
  4. Click "Apply"

← Structure de l'application | Sommaire | Suivant : Référence API →