} else if (activeSourceMode === 'solar_only' || activeSourceMode === 'solar_potential') { // Potentiel autorise step up aussi desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = clamp(currentReferenceA + currentStepUpA, currentMinA, physicalCapA); state = probeSuccessNow ? 'probe_success_step_up' : (batteryPriorityMode ? 'charging_step_up_battery' : 'charging_step_up_forecast'); currentDecision = 'step_up'; dynamicOk = true; reason.push("Hausse prudente du courant"); } else { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = clamp(Math.min(currentReferenceA, physicalCapA), currentMinA, physicalCapA); state = probeSuccessNow ? 'probe_success_hold' : activeSourceMode === 'grid_hc_allowed' ? 'charging_hold_grid_hc' : cloudDebtActive ? 'charging_hold_cloud_tolerance' : 'charging_hold'; currentDecision = 'hold'; dynamicOk = true; mustStop = false; reason.push("Maintien du courant"); } } } else { const startConditionsOk = (sourceMode === 'grid_hc_allowed' || sourceMode === 'grid_forced') ? gridStartOk : // Ajout de 'grid_forced' sourceMode === 'solar_only' || sourceMode === 'solar_potential' ? solarStartOk : // Potentiel autorise démarrage aussi sourceMode === 'hybrid_probe' ? probeStartOk : false; if (profile === 'outside_window') { // outside_window n'est plus un mur absolu en mode force ou avec potentiel if (sourceMode === 'solar_potential' || isForceMode) { // Continue à chercher startConditionsOk... } else { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = 'blocked_outside_window'; currentDecision = 'hold'; dynamicOk = false; mustStop = false; nextBlockReason = 'outside_window'; nextBlockedUntilStamp = nextAllowedWindowStartMs !== null ? formatParisStampFromMs(nextAllowedWindowStartMs) : now.stamp; reason.push("Hors fenêtre autorisée (pas de potentiel confirmé ni forcé)"); } } else if (!canRunAtMinCurrent) { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = 'blocked_by_capacity_min_current'; currentDecision = 'hold'; dynamicOk = false; mustStop = false; nextBlockReason = 'battery_protection_stop'; nextBlockedUntilStamp = formatParisStampFromMs(nowMs + 10 * 60000); reason.push("Capacité insuffisante pour courant mini"); } else if (sourceMode === 'blocked') { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = profile === 'night_hc' ? 'night_no_grid_hc_lock' : 'idle_wait_source'; currentDecision = 'hold'; dynamicOk = false; mustStop = false; nextBlockReason = profile === 'night_hc' ? 'outside_window' : 'source_unavailable'; nextBlockedUntilStamp = profile === 'night_hc' && nextAllowedWindowStartMs !== null ? formatParisStampFromMs(nextAllowedWindowStartMs) : formatParisStampFromMs(nowMs + 15 * 60000); reason.push(profile === 'night_hc' ? "Nuit sans autorisation HC réseau" : "Source non autorisée ou insuffisante"); } else if (startBlockedByReason) { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = 'wait_reason_lock'; currentDecision = 'hold'; dynamicOk = false; mustStop = false; nextBlockReason = lastBlockReason; nextBlockedUntilStamp = blockedUntilAt || now.stamp; reason.push(`Blocage anti-cliquetis: ${lastBlockReason}`); } else if (!startConditionsOk) { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = 'idle_wait_conditions'; currentDecision = 'hold'; dynamicOk = false; mustStop = false; reason.push("Conditions de démarrage non réunies"); } else if (!minStopElapsed) { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = 'wait_min_stop'; currentDecision = 'hold'; dynamicOk = false; mustStop = false; reason.push("Temps mini OFF non écoulé"); } else { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = sourceMode === 'hybrid_probe' ? clamp(probeCurrentA, currentMinA, physicalCapA) : currentMinA; state = sourceMode === 'grid_hc_allowed' ? 'start_grid_hc_min_current' : sourceMode === 'hybrid_probe' ? 'probe_start_6a' : sourceMode === 'solar_potential' ? 'start_forecast_solar_potential' : // NOUVEAU STATE batteryFullHarvestMode ? 'start_min_current_battery_full_harvest' : forecastCommitMode ? 'start_min_current_forecast_commit' : 'start_min_current'; currentDecision = 'start'; dynamicOk = true; mustStop = false; nextBlockReason = 'none'; // Clean blocking logic: set reason to none on start nextBlockedUntilStamp = now.stamp; setProbeStartedAt = sourceMode === 'hybrid_probe'; reason.push( sourceMode === 'grid_hc_allowed' ? "Démarrage en fenêtre HC réseau" : sourceMode === 'hybrid_probe' ? "Démarrage en mode sonde" : sourceMode === 'solar_potential' ? "Démarrage par potentiel solaire confirmé (SOC>=85%)" // NOUVEAU REASON TEXT : batteryFullHarvestMode ? "Démarrage harvest solaire" : forecastCommitMode ? "Démarrage forecast commit" : "Démarrage prudent à courant mini" ); } }