From cc763ddfc8cf32d84f61c905ffe56d05d765a152 Mon Sep 17 00:00:00 2001 From: Johannes Haller Date: Mon, 23 Feb 2026 15:43:24 +0100 Subject: [PATCH] Fix index bounds and current-quarter handling Clamp endIndex to the lengths of production/consumption arrays to avoid out-of-bounds slices and change the subList check to require more than one quarter (>1) so only full future quarters are aggregated. Also add guards when reading index 0 values to handle empty arrays and null entries, defaulting to 0 for current production/consumption. Should fix: https://github.com/OpenEMS/openems/issues/3530 --- .../ess/gridoptimizedcharge/DelayCharge.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/io.openems.edge.controller.ess.gridoptimizedcharge/src/io/openems/edge/controller/ess/gridoptimizedcharge/DelayCharge.java b/io.openems.edge.controller.ess.gridoptimizedcharge/src/io/openems/edge/controller/ess/gridoptimizedcharge/DelayCharge.java index dd906454730..e17f42956b7 100644 --- a/io.openems.edge.controller.ess.gridoptimizedcharge/src/io/openems/edge/controller/ess/gridoptimizedcharge/DelayCharge.java +++ b/io.openems.edge.controller.ess.gridoptimizedcharge/src/io/openems/edge/controller/ess/gridoptimizedcharge/DelayCharge.java @@ -549,7 +549,8 @@ protected static int calculateAvailEnergy(Integer[] quarterHourlyProduction, Int int dailyEndIndex = DelayCharge.getAsZonedDateTime(targetMinute, clock).get(MINUTE_OF_DAY) / 15; // Relevant quarter hours - int endIndex = dailyEndIndex - dailyStartIndex; + int endIndex = Math.min(dailyEndIndex - dailyStartIndex, + Math.min(quarterHourlyProduction.length, quarterHourlyConsumption.length)); float productionEnergyTotal = 0; float consumptionEnergyTotal = 0; @@ -558,7 +559,7 @@ protected static int calculateAvailEnergy(Integer[] quarterHourlyProduction, Int * Summarize and calculate every quarterly power, if there is more than one * quarter hour left */ - if (endIndex > 0) { + if (endIndex > 1) { List productionList = Arrays.asList(quarterHourlyProduction).subList(1, endIndex); List consumptionList = Arrays.asList(quarterHourlyConsumption).subList(1, endIndex); @@ -576,8 +577,12 @@ protected static int calculateAvailEnergy(Integer[] quarterHourlyProduction, Int // Add energy of the first index separately to ignore the already passed energy float timeOfQuarterLeft = ChronoUnit.SECONDS.between(now, predictionStartQuarterHour.plusMinutes(15)) / 60.0f / 60.0f; - var currentProduction = quarterHourlyProduction[0] == null ? 0 : quarterHourlyProduction[0]; - var currentConsumption = quarterHourlyConsumption[0] == null ? 0 : quarterHourlyConsumption[0]; + var currentProduction = quarterHourlyProduction.length > 0 && quarterHourlyProduction[0] != null + ? quarterHourlyProduction[0] + : 0; + var currentConsumption = quarterHourlyConsumption.length > 0 && quarterHourlyConsumption[0] != null + ? quarterHourlyConsumption[0] + : 0; float leftProdEnergy = timeOfQuarterLeft * currentProduction; float leftConsEnergy = timeOfQuarterLeft * currentConsumption;