← Estructura de la aplicación | Contenido | Siguiente: Referencia API →
4. Modos de operación del RouterController
4.1 Descripción general de los modos
RouterController soporta 6 modos de operación, cada uno optimizado para un escenario de uso específico.
Tabla de modos
| Modo | Enum | Control del dimmer | Control P_grid | Sensores requeridos | Aplicación |
|---|---|---|---|---|---|
| OFF | 0 | 0% (fijo) | ❌ No | - | Mantenimiento, apagado |
| AUTO | 1 | Automático | ✅ P_grid → 0 | Corriente de red | Enrutador solar estándar |
| ECO | 2 | Semiautomático | ⚠️ Solo importación | Corriente de red | Prevención de exportación |
| OFFGRID | 3 | Automático | ❌ No | Corriente solar | Sistemas aislados |
| MANUAL | 4 | Fijo | ❌ No | - | Tarifa nocturna, pruebas |
| BOOST | 5 | 100% (fijo) | ❌ No | - | Calentamiento forzado |
4.2 Modo OFF (0) – Desactivado
Descripción
Apagado completo del control del dimmer. Se utiliza para mantenimiento, depuración o cuando no se requiere control de carga.
Algoritmo
void RouterController::processOffMode() {
// Dimmer always 0%
if (m_status.dimmer_percent != 0) {
applyDimmerLevel(0);
}
m_status.state = RouterState::IDLE;
}
Parámetros
Sin parámetros configurables.
Sensores requeridos
No se requieren sensores (las mediciones continúan pero no se utilizan).
Comportamiento
- Nivel del dimmer: 0% (constante)
- P_grid: No controlado
- Estado: IDLE
- Mediciones: Continúan (PowerMeterADC funciona)
- Interfaz web: Disponible
- Comandos serie: Funcionan
Cuándo usar
- ✅ Mantenimiento del dispositivo
- ✅ Prueba de sensores sin control
- ✅ Depuración del sistema
- ✅ Desconexión temporal de la carga
Ejemplo de uso
// 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 Modo AUTO (1) – Enrutador solar automático
Descripción
Modo principal del enrutador solar. Equilibra automáticamente la potencia de red (P_grid) a cero, redirigiendo el exceso de energía solar a la carga en lugar de exportarlo a la red.
Algoritmo
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);
}
Comportamiento según el signo de P_grid
| Situación | P_grid | Error | Delta | Acción |
|---|---|---|---|---|
| Exportación a la red | < 0 (negativo) | > 0 (positivo) | > 0 | Aumentar dimmer → más carga |
| Importación de la red | > 0 (positivo) | < 0 (negativo) | < 0 | Disminuir dimmer → menos carga |
| Equilibrio | ≈ 0 (dentro del umbral) | ≈ 0 | 0 | Mantener nivel actual |
Parámetros
control_gain (Kp)
Descripción: Coeficiente del controlador proporcional. Determina la velocidad de respuesta a los cambios de P_grid.
Fórmula: delta = error / control_gain
Rango: 10.0 - 1000.0
Predeterminado: 200.0
Impacto:
- Kp menor (más rápido):
- ✅ Respuesta rápida a los cambios
- ❌ Posibles oscilaciones
-
Ejemplo: Kp = 50 → rápido, pero inestable
-
Kp mayor (más lento):
- ✅ Control suave
- ✅ Estabilidad
- ❌ Respuesta lenta
- Ejemplo: Kp = 500 → lento, pero estable
Recomendaciones:
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
Descripción: Umbral de equilibrio en Watts. Si |P_grid| < umbral, el sistema se considera equilibrado.
Rango: 0.0 - 100.0 W
Predeterminado: 10.0 W
Impacto:
- Umbral menor:
- ✅ Equilibrio más preciso (P_grid más cercano a 0)
-
❌ Más ajustes (desgaste del TRIAC)
-
Umbral mayor:
- ✅ Menos ciclos de conmutación
- ❌ Equilibrio menos preciso
Recomendaciones:
Load Power | Recommended Threshold
-------------------------|----------------------
< 500 W | 5 - 10 W
500 - 1500 W | 10 - 20 W
> 1500 W | 20 - 50 W
Sensores requeridos
Mínimo:
- ✅ Current Grid (requerido) – para la determinación de P_grid
- ✅ Voltage (recomendado) – para el cálculo de potencia
Opcional:
- ⚪ Current Load – para monitoreo de consumo
- ⚪ Current Solar – para monitoreo de generación
Ejemplos de operación
Ejemplo 1: Excedente solar
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 ✅
Ejemplo 2: Una nube cubre el sol
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 ✅
Configuración a través de interfaces
// 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 Modo ECO (2) – Economía (Anti-Exportación)
Descripción
Modo de prevención de exportación. Evita exportar electricidad a la red, pero permite la importación. Se utiliza cuando la exportación no es rentable o está prohibida.
Algoritmo
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
}
}
Diferencias con AUTO
| Aspecto | AUTO | ECO |
|---|---|---|
| Exportación | Impedida (dimmer aumenta) | Permitida (dimmer no aumenta) |
| Importación | Impedida (dimmer disminuye) | Permitida (dimmer disminuye lentamente) |
| Velocidad de respuesta | Rápida (Kp) | Más lenta (Kp × 1,5) |
| Objetivo | P_grid = 0 | P_grid ≥ 0 |
Comportamiento
- P_grid > umbral (importación):
- Disminuir lentamente el dimmer
-
Velocidad: Kp × 1,5 (más lento que AUTO)
-
P_grid < 0 (exportación):
- NO aumentar el dimmer
-
Mantener el nivel actual
-
P_grid ≈ 0:
- Mantener el nivel actual
Parámetros
Iguales que AUTO:
- control_gain – afecta la velocidad de disminución durante la importación
- balance_threshold – umbral para la determinación del equilibrio
Sensores requeridos
- ✅ Current Grid (requerido)
- ✅ Voltage (recomendado)
Cuándo usar
- ✅ Sin contrato de exportación a la red
- ✅ Tarifa de exportación desfavorable (< costo de importación)
- ✅ Restricción técnica de exportación
- ✅ Protección contra exportación con red inestable
Ejemplo de operación
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 Modo OFFGRID (3) – Aislado de la red
Descripción
Modo para sistemas autónomos con paneles solares y baterías, sin conexión a la red. Utiliza el exceso de energía solar para la carga.
Algoritmo
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);
}
}
Características
- NO utiliza P_grid (el sensor de red puede estar ausente)
- Utiliza P_solar para determinar la potencia disponible
- Conservador: 80% de la potencia disponible (protección de batería)
- Prioridad: Carga principal → Baterías → Calentador
Parámetros
- control_gain – afecta la velocidad de aumento de carga
- balance_threshold – potencia solar mínima para la activación
- Margen de seguridad: 0,8 (80%) – codificado fijo
Sensores requeridos
Mínimo:
- ✅ Current Solar (requerido) – para la determinación de generación
- ✅ Voltage (recomendado)
Opcional:
- ⚪ Current Load – para un control más preciso
- ❌ Current Grid – NO requerido (puede estar ausente)
Cuándo usar
- ✅ Sistemas aislados de la red
- ✅ Paneles solares + baterías
- ✅ Sin conexión a la red
- ✅ Maximizar el uso de energía solar
Ejemplo de operación
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 Modo MANUAL (4) – Manual
Descripción
Nivel fijo del dimmer establecido por el usuario. Sin control automático.
Algoritmo
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;
}
Parámetros
- manual_level – nivel del dimmer (0-100%)
Sensores requeridos
No se requieren sensores (las mediciones continúan para monitoreo).
Cuándo usar
- ✅ Tarifa nocturna (establecer 100% para la noche)
- ✅ Pruebas de carga
- ✅ Mantenimiento de temperatura (establecer 50%)
- ✅ Depuración del sistema
Ejemplo de uso
// 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}
Escenario: Tarifa nocturna
# 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 Modo BOOST (5) – Calentamiento forzado
Descripción
Dimmer fijo al 100%. Potencia máxima a la carga.
Algoritmo
void RouterController::processBoostMode() {
// Always 100%
if (m_status.dimmer_percent != 100) {
applyDimmerLevel(100);
}
m_status.state = RouterState::AT_MAXIMUM;
}
Parámetros
Sin parámetros configurables (siempre 100%).
Sensores requeridos
No requeridos.
Cuándo usar
- ✅ Calentamiento rápido del calentador de agua
- ✅ Aprovechamiento de tarifa económica
- ✅ Modo de emergencia
Advertencias
⚠️ ADVERTENCIA:
- Alto consumo de red
- Posible sobrecalentamiento de la carga
- Monitorear la temperatura manualmente
- No dejar sin supervisión
Ejemplo de uso
// Enable BOOST
router.setMode(RouterMode::BOOST);
// Return to AUTO after 2 hours
delay(2 * 60 * 60 * 1000);
router.setMode(RouterMode::AUTO);
4.8 Cambio entre modos
Cambio seguro
Al cambiar de modo, RouterController:
- Registra el cambio de modo
- Reinicia el estado interno
- Aplica el nuevo algoritmo
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;
}
Recomendaciones de cambio
Transiciones seguras:
OFF ↔ AUTO ✅ Safe
OFF ↔ MANUAL ✅ Safe
AUTO ↔ ECO ✅ Safe (similar algorithms)
MANUAL ↔ BOOST ✅ Safe
Precaución:
AUTO → BOOST ⚠️ Sharp power spike
OFFGRID → AUTO ⚠️ Different sensors
Secuencias de comandos
# 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 Configuraciones mínimas de sensores
Para cada modo
| Modo | Sensores requeridos | Opcional | Nota |
|---|---|---|---|
| OFF | - | - | Sensores no utilizados |
| AUTO | Voltage, Current Grid | Current Load, Current Solar | Grid necesario para P_grid |
| ECO | Voltage, Current Grid | Current Load, Current Solar | Grid necesario para P_grid |
| OFFGRID | Voltage, Current Solar | Current Load | Grid NO requerido |
| MANUAL | - | Voltage, Current Grid | Solo para monitoreo |
| BOOST | - | Voltage, Current Grid | Solo para monitoreo |
Configuración mínima (enrutador solar)
Para los modos AUTO/ECO:
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
Resultado:
- ✅ Medición de P_grid (para equilibrio)
- ✅ Control del dimmer
- ❌ Sin monitoreo solar/carga
Configuración completa
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
Resultado:
- ✅ Monitoreo completo del sistema
- ✅ Todos los modos soportados
- ✅ Análisis detallado
4.10 Configuración de parámetros a través de interfaces
Por comandos serie
# 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
Por REST API
# 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}'
Por interfaz web
- Abrir el panel de control:
http://192.168.4.1/ - Seleccionar modo (6 botones)
- Para MANUAL: mover el deslizador
- Click "Apply"
← Estructura de la aplicación | Contenido | Siguiente: Referencia API →