desiredPermission = true; desiredLatch = true; desiredCurrentA = clamp(probeCurrentA, currentMinA, physicalCapA); state = 'probe_hold'; currentDecision = 'hold'; dynamicOk = true; mustStop = false; reason.push(`Mode sonde actif à ${round1(desiredCurrentA)}A`); } } else { const activeSourceMode = probeSuccessNow ? 'solar_only' : sourceMode; const holdConditionsOk = activeSourceMode === 'grid_hc_allowed' || activeSourceMode === 'grid_forced' ? gridHoldOk : // Ajout ici aussi activeSourceMode === 'solar_only' || activeSourceMode === 'solar_potential' ? solarHoldOk : probeHoldGuardOk; if (activeSourceMode === 'blocked') { if (minRunElapsed) { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = 'stop_source_lost'; currentDecision = 'stop'; dynamicOk = false; mustStop = true; nextBlockReason = profile === 'outside_window' ? 'outside_window' : 'source_unavailable'; nextBlockedUntilStamp = profile === 'outside_window' && nextAllowedWindowStartMs !== null ? formatParisStampFromMs(nextAllowedWindowStartMs) : formatParisStampFromMs(nowMs + minStopMinutes * 60000); reason.push("Source autorisée perdue"); } else { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = clamp(Math.min(currentReferenceA, physicalCapA), currentMinA, physicalCapA); state = 'hold_min_run_source_lost'; currentDecision = 'hold'; dynamicOk = false; mustStop = false; reason.push("Source perdue mais maintien jusqu'au mini ON"); } } else if (!holdConditionsOk) { if (minRunElapsed) { desiredCharging = false; desiredPermission = false; desiredLatch = false; desiredCurrentA = currentMinA; state = 'stop_conditions_lost'; currentDecision = 'stop'; dynamicOk = false; mustStop = true; nextBlockReason = 'battery_protection_stop'; nextBlockedUntilStamp = formatParisStampFromMs(nowMs + 10 * 60000); reason.push("Conditions de maintien perdues"); } else { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = clamp(Math.min(currentReferenceA, physicalCapA), currentMinA, physicalCapA); state = 'hold_min_run'; currentDecision = 'hold'; dynamicOk = true; mustStop = false; reason.push("Maintien jusqu'au temps mini ON"); } } else if ((currentReferenceA > physicalCapA) && currentCooldownElapsed) { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = Math.max( currentMinA, Math.min(currentReferenceA - Math.max(currentStepDownA, 2), physicalCapA) ); state = 'charging_step_down_system_cap'; currentDecision = 'step_down'; dynamicOk = true; reason.push("Réduction pour respecter la capacité système"); } else if (shouldStepDownVebusPower) { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = Math.max( currentMinA, Math.min(currentReferenceA - Math.max(currentStepDownA + 1, 3), physicalCapA) ); state = 'charging_step_down_vebus_power'; currentDecision = 'step_down_fast'; dynamicOk = true; reason.push("Baisse rapide: puissance VE.Bus élevée"); } else if (shouldStepDownVebusVoltage) { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = Math.max( currentMinA, Math.min(currentReferenceA - Math.max(currentStepDownA + 1, 3), physicalCapA) ); state = 'charging_step_down_dc_voltage'; currentDecision = 'step_down_fast'; dynamicOk = true; reason.push("Baisse rapide: tension DC basse"); } else if (activeSourceMode === 'grid_hc_allowed' && gridShouldStepDownBattery) { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = Math.max( currentMinA, Math.min(currentReferenceA - currentStepDownA, physicalCapA) ); state = 'charging_step_down_grid_guard'; currentDecision = 'step_down'; dynamicOk = true; reason.push("Réduction HC: la batterie commence à participer"); } else if (activeSourceMode === 'solar_only' && solarShouldStepDownCloudDebt) { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = Math.max( currentMinA, Math.min(currentReferenceA - Math.max(currentStepDownA, 2), physicalCapA) ); state = 'charging_step_down_cloud_debt'; currentDecision = 'step_down'; dynamicOk = true; reason.push("Réduction: dette nuage trop élevée"); } else if (activeSourceMode === 'solar_only' && solarShouldStepDownBattery) { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = Math.max( currentMinA, Math.min(currentReferenceA - currentStepDownA, physicalCapA) ); state = 'charging_step_down_battery'; currentDecision = 'step_down'; dynamicOk = true; reason.push("Réduction: batterie trop sollicitée"); } else if (activeSourceMode === 'grid_hc_allowed' && gridShouldStepUp) { desiredCharging = true; desiredPermission = true; desiredLatch = true; desiredCurrentA = clamp(currentReferenceA + currentStepUpA, currentMinA, physicalCapA); state = 'charging_step_up_grid_hc'; currentDecision = 'step_up'; dynamicOk = true;