// ===================================================== // STEP-UP LOGIC // ===================================================== const stepUpByBatteryReserve = batteryPriorityMode && parsed.batteryCurrentA >= batteryChargeReserveDynamicA; const stepUpByForecastMode = !batteryPriorityMode && ( parsed.pvPowerW >= params.pvHoldMinW || parsed.pvPowerAvg10mW >= params.pvHoldMinW ) && derived.forecastBufferKwh >= -1 && derived.projectedEndSocAfterCharge >= (derived.endDayGuardSoc - 5) && cloudToleranceOk; const solarShouldStepUp = lifecycle.currentCooldownElapsed && derived.currentReferenceA < derived.physicalCapA && derived.physicalCapA >= params.currentMinA && !derived.vebusAcOutSoftReached && !derived.vebusDcVoltageSoftLow && !derived.houseLoadHighVsHeadroom && ( stepUpByBatteryReserve || stepUpByForecastMode || parsed.pvPowerW >= (context.effectivePvStartMinW + 400) ); const gridShouldStepUp = lifecycle.currentCooldownElapsed && derived.currentReferenceA < derived.physicalCapA && derived.physicalCapA >= params.currentMinA && !derived.vebusAcOutSoftReached && !derived.vebusDcVoltageSoftLow && parsed.batteryCurrentA >= gridBatterySoftDynamicA && !derived.houseLoadHighVsHeadroom; // ===================================================== // STEP-DOWN LOGIC // ===================================================== const solarShouldStepDownBattery = parsed.batteryCurrentA <= batteryDischargeSoftDynamicA && lifecycle.currentCooldownElapsed && derived.currentReferenceA > params.currentMinA; const solarShouldStepDownCloudDebt = !cloudToleranceOk && lifecycle.currentCooldownElapsed && derived.currentReferenceA > params.currentMinA; const gridShouldStepDownBattery = parsed.batteryCurrentA < gridBatterySoftDynamicA && lifecycle.currentCooldownElapsed && derived.currentReferenceA > params.currentMinA; const shouldStepDownVebusPower = derived.vebusAcOutSoftReached && lifecycle.currentCooldownElapsed && derived.currentReferenceA > params.currentMinA; const shouldStepDownVebusVoltage = derived.vebusDcVoltageSoftLow && lifecycle.currentCooldownElapsed && derived.currentReferenceA > params.currentMinA; const shouldStepDownOverload = derived.anyVebusOverload && lifecycle.currentCooldownElapsed && derived.currentReferenceA > params.currentMinA; const shouldStopOverloadAtMin = derived.anyVebusOverload && derived.currentReferenceA <= params.currentMinA && sessionObservedActive; // ===================================================== // HARD STOPS / PROTECTIONS // ===================================================== const batteryCurrentHardExceeded = parsed.batteryCurrentA <= batteryDischargeHardDynamicA; // overload volontairement exclu du hard stop immédiat const mustStopHard = derived.anyVebusLowBattery || derived.vebusDcVoltageHardLow || derived.vebusAcOutHardReached || batteryCurrentHardExceeded; const gridBatteryProtectionStop = sessionObservedActive && isGridSource && parsed.batteryCurrentA < gridBatteryHardDynamicA; // ===================================================== // OUTPUT // ===================================================== return [{ json: { ...prev, batteryPolicy: { socBand, batteryDischargeSoftDynamicA, batteryDischargeHardDynamicA, batteryChargeReserveDynamicA, batterySoftToleranceMinutes, batteryHardToleranceSeconds, batteryRecoveryMinutes, gridBatterySoftDynamicA, gridBatteryHardDynamicA, gridForceChargeRelaxSoftA, gridForceChargeRelaxHardA, houseSpikeDetected, solarPotentialContext, }, locks: { nextAllowedWindowStartMs, blockActive, blockStillRelevant, startBlockedByReason, }, cloud: { sessionObservedActive, batteryNetPowerW, cloudDebtNextKwh, cloudDebtMeaningful, cloudEventDischargingNow, continuingCloudEvent, enteringCloudDebt, cloudDebtActive, cloudDebtStartedMs, cloudDebtDurationMinutes, effectiveCloudToleranceMinutes, cloudToleranceOk, }, modes: { batteryFullHarvestMode, forecastCommitMode, batteryPriorityMode, }, safeguards: { isGridSource, commonSafetyStartOk, commonSafetyHoldOk, profileSocStartFloor, profileSocHoldFloor, profileBatteryDischargeFloorA, batteryCurrentHardExceeded, mustStopHard, gridBatteryProtectionStop, }, conditions: { solarStartOk, solarHoldOk, gridStartOk, gridHoldOk, probeStartOk, probeHoldGuardOk, probeWindowActive, probeElapsedReached, probeSuccessNow, probeFailedNow, solarShouldStepUp, gridShouldStepUp, solarShouldStepDownBattery, solarShouldStepDownCloudDebt, gridShouldStepDownBattery, shouldStepDownVebusPower, shouldStepDownVebusVoltage, shouldStepDownOverload, shouldStopOverloadAtMin, } } }];