From 75e4694183009ce1df5534afab04cf16ccc88ed0 Mon Sep 17 00:00:00 2001 From: Luc-Sol Date: Tue, 15 Jul 2025 17:36:09 +0200 Subject: [PATCH 1/6] Refactoring & Cleanup - Refactored small things like: getCurrentStateOfCharge() -> getCurrentStateOfCharge_fr() - removed v_batterySOC_fr from GC canvas, if you want to know the current SOC just ask the asset! - getCurrentStateOfCharge_fr() is now a method of the J_EAStorage (and J_EAEV) not the base J_EA. - Added a new function f_batteryManagement that has the switch statement on the OL_BatteryOperationMode, instead of it being in the f_operateFlexAssets - Cleaned the f_batteryManagement functions for SelfConsumption, Price and PeakShavingSimple (previously Balance) --- Zero_engine.alpx | 44 ++- .../GCEnergyConversion/Code/Functions.java | 9 +- .../GCEnergyConversion/Code/Functions.xml | 4 - .../GCEnergyProduction/Code/Functions.java | 42 +-- .../Code/AdditionalClassCode.java | 22 +- _alp/Agents/GCGridBattery/Code/Functions.java | 107 +++--- _alp/Agents/GCGridBattery/Code/Functions.xml | 37 +- .../GCGridBattery/Levels/Level.level.xml | 4 +- .../GCHouse/Code/AdditionalClassCode.java | 4 +- _alp/Agents/GCHouse/Code/Functions.java | 31 +- _alp/Agents/GCHouse/Code/Functions.xml | 4 - _alp/Agents/GCHouse/Levels/Level.level.xml | 2 +- _alp/Agents/GCIndustry/AOC.GCIndustry.xml | 1 + _alp/Agents/GCIndustry/Code/Functions.java | 10 +- .../Agents/GCNeighborhood/Code/Functions.java | 20 +- _alp/Agents/GCNeighborhood/Code/Functions.xml | 12 - _alp/Agents/GCNeighborhood/Variables.xml | 19 + _alp/Agents/GCUtility/Code/Functions.java | 53 +-- .../Agents/GridConnection/Code/Functions.java | 330 ++++++++++++------ _alp/Agents/GridConnection/Code/Functions.xml | 113 ++++-- .../GridConnection/Levels/Level.level.xml | 96 ++--- _alp/Agents/GridConnection/Variables.xml | 45 +-- _alp/Classes/Class.J_BatteryAlgorithmBas.java | 2 +- _alp/Classes/Class.J_EA.java | 18 - _alp/Classes/Class.J_EABuilding.java | 11 +- _alp/Classes/Class.J_EADieselVehicle.java | 1 - _alp/Classes/Class.J_EAEV.java | 81 +++-- _alp/Classes/Class.J_EAHydrogenVehicle.java | 1 - _alp/Classes/Class.J_EAStorage.java | 30 +- _alp/Classes/Class.J_EAStorageElectric.java | 34 +- _alp/Classes/Class.J_EAStorageGas.java | 30 +- _alp/Classes/Class.J_EAStorageHeat.java | 13 +- 32 files changed, 604 insertions(+), 626 deletions(-) diff --git a/Zero_engine.alpx b/Zero_engine.alpx index b5e55d46..a37b4a6a 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -963,44 +963,52 @@ 1668693527446 + + diff --git a/_alp/Agents/GCEnergyConversion/Code/Functions.java b/_alp/Agents/GCEnergyConversion/Code/Functions.java index 50014481..e7fef52e 100644 --- a/_alp/Agents/GCEnergyConversion/Code/Functions.java +++ b/_alp/Agents/GCEnergyConversion/Code/Functions.java @@ -86,7 +86,7 @@ } /*ALCODEEND*/} -double f_batteryManagementBalanceCoop(double batterySOC) +double f_batteryManagementBalanceCoop() {/*ALCODESTART::1707149801187*/ if ((p_batteryAsset).getStorageCapacity_kWh() != 0){ if( p_owner != null ) { @@ -112,7 +112,7 @@ double FeedforwardGain_kWpKw = 0.1; // Feedforward based on current surpluss in Coop double chargeOffset_kW = 0; // Charging 'bias', basically increases SOC setpoint slightly during the whole day. double chargeSetpoint_kW = 0; - chargeSetpoint_kW = FeedforwardGain_kWpKw * (currentCoopElectricitySurplus_kW - chargeOffset_kW) + (SOC_setp_fr - batterySOC) * FeedbackGain_kWpSOC; + chargeSetpoint_kW = FeedforwardGain_kWpKw * (currentCoopElectricitySurplus_kW - chargeOffset_kW) + (SOC_setp_fr - p_batteryAsset.getCurrentStateOfCharge_fr()) * FeedbackGain_kWpSOC; chargeSetpoint_kW = min(max(chargeSetpoint_kW, availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging! p_batteryAsset.v_powerFraction_fr = max(-1,min(1, chargeSetpoint_kW / p_batteryAsset.getCapacityElectric_kW())); // Convert to powerFraction and limit power //traceln("Coop surpluss " + currentCoopElectricitySurplus_kW + "kW, Battery charging power " + p_batteryAsset.v_powerFraction_fr*p_batteryAsset.j_ea.getElectricCapacity_kW() + " kW at " + currentBatteryStateOfCharge*100 + " % SOC"); @@ -235,12 +235,11 @@ // Operate battery if (p_batteryAsset != null){ - v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge(); if( p_batteryOperationMode == OL_BatteryOperationMode.BALANCE) { - f_batteryManagementBalanceCoop( v_batterySOC_fr ); + f_batteryManagementBalanceCoop(); } else { - f_batteryManagementPrice( v_batterySOC_fr ); + f_batteryManagementPrice(); } p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr); //v_batteryPowerElectric_kW = p_batteryAsset.electricityConsumption_kW - p_batteryAsset.electricityProduction_kW; diff --git a/_alp/Agents/GCEnergyConversion/Code/Functions.xml b/_alp/Agents/GCEnergyConversion/Code/Functions.xml index 24022882..49cd46c2 100644 --- a/_alp/Agents/GCEnergyConversion/Code/Functions.xml +++ b/_alp/Agents/GCEnergyConversion/Code/Functions.xml @@ -56,10 +56,6 @@ false true true - - - - diff --git a/_alp/Agents/GCEnergyProduction/Code/Functions.java b/_alp/Agents/GCEnergyProduction/Code/Functions.java index f3c04d13..57074f53 100644 --- a/_alp/Agents/GCEnergyProduction/Code/Functions.java +++ b/_alp/Agents/GCEnergyProduction/Code/Functions.java @@ -6,49 +6,9 @@ } } -// Determine EV charging f_manageCharging(); -//v_currentPowerElectricity_kW += v_evChargingPowerElectric_kW; -// Operate battery -/*if (p_batteryAsset != null){ - v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge(); - if( p_batteryOperationMode == OL_BatteryOperationMode.BALANCE) { - f_batteryManagementBalanceCoop( v_batterySOC_fr ); - } - else { - f_batteryManagementPriceGrid( v_batterySOC_fr ); - } - double[] arr = p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr); - v_batteryPowerElectric_kW = arr[4] - arr[0]; - //v_batteryPowerElectric_kW = p_batteryAsset.electricityConsumption_kW - p_batteryAsset.electricityProduction_kW; - //v_currentPowerElectricity_kW += v_batteryPowerElectric_kW; -}*/ - -if ( p_batteryAsset != null ) { - if ( p_batteryAsset.getStorageCapacity_kWh() != 0.0) { - v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge(); - if( p_batteryOperationMode == OL_BatteryOperationMode.BALANCE){ - //f_batteryManagementGridLoad(v_batterySOC_fr); - f_batteryManagementBalance(v_batterySOC_fr); -// } else if (p_batteryOperationMode == OL_BatteryOperationMode.BALANCE_SUPPLY){ // Tries to minimize supply peaks -// f_batteryManagementBalanceSupply(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.PRICE){ - f_batteryManagementPrice(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.NODAL_PRICING){ - f_batteryManagementNodalPricing(v_batterySOC_fr); - } - - //Pair flowsPair = p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr); - //J_FlowsMap flowsMap = flowsPair.getFirst(); - - p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr); - - //v_batteryPowerElectric_kW = flowsMap.get(OL_EnergyCarriers.ELECTRICITY); - //v_batteryPowerElectric_kW = p_batteryAsset.electricityConsumption_kW - p_batteryAsset.electricityProduction_kW; - //v_currentPowerElectricity_kW += v_batteryPowerElectric_kW; - } -} +f_manageBattery(); /*ALCODEEND*/} diff --git a/_alp/Agents/GCGridBattery/Code/AdditionalClassCode.java b/_alp/Agents/GCGridBattery/Code/AdditionalClassCode.java index d8ce7db8..1369e0bf 100644 --- a/_alp/Agents/GCGridBattery/Code/AdditionalClassCode.java +++ b/_alp/Agents/GCGridBattery/Code/AdditionalClassCode.java @@ -1,24 +1,4 @@ -/*@Override -public void f_connectToChild(J_EA j_ea){ - f_connectToChild_overwrite(j_ea); -}*/ - @Override public void f_operateFlexAssets(){ f_operateFlexAssets_overwrite(); -} - -@Override -public void f_batteryManagementBalance( double batterySOC ){ - f_batteryManagementBalanceGrid( batterySOC ); -} - -@Override -public void f_batteryManagementPrice( double batterySOC ){ - f_batteryManagementPriceGrid( batterySOC ); -} - -/*@Override // Why? -public void f_calculateEnergyBalance(){ - f_calculateEnergyBalance_overwrite(); -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/_alp/Agents/GCGridBattery/Code/Functions.java b/_alp/Agents/GCGridBattery/Code/Functions.java index 090c0627..3f8923f5 100644 --- a/_alp/Agents/GCGridBattery/Code/Functions.java +++ b/_alp/Agents/GCGridBattery/Code/Functions.java @@ -61,34 +61,7 @@ else if(EA.j_ea instanceof J_EAStorageElectric && ((J_EAStorageElectric)EA.j_ea) return; } -if ( p_batteryAsset != null ) { - if ( p_batteryAsset.getStorageCapacity_kWh() != 0.0 && p_batteryAsset.getCapacityElectric_kW() != 0.0) { - v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge(); - if( p_batteryOperationMode == OL_BatteryOperationMode.BALANCE){ - //f_batteryManagementGridLoad(v_batterySOC_fr); - f_batteryManagementBalanceGrid(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.BALANCE_SUPPLY){ // Tries to minimize supply peaks - f_batteryManagementBalanceSupply(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.PRICE){ - f_batteryManagementPrice(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.NODAL_PRICING){ - f_batteryManagementPriceGrid(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.BALANCE_COOP){ - f_batteryManagementBalanceCOOP(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.BATTERY_ALGORITHM_BAS){ - f_batteryManagementBas(v_batterySOC_fr); - } else if (p_batteryOperationMode == OL_BatteryOperationMode.SELF_CONSUMPTION){ - f_batteryManagementSelfConsumption(); - } - - p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr); - //J_FlowsMap flowsMap = flowsPair.getFirst(); - //v_batteryPowerElectric_kW = flowsMap.get(OL_EnergyCarriers.ELECTRICITY); - v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge(); - //v_batteryPowerElectric_kW = p_batteryAsset.electricityConsumption_kW - p_batteryAsset.electricityProduction_kW; - //v_currentPowerElectricity_kW += v_batteryPowerElectric_kW; - } -} +f_manageBattery(); /*ALCODEEND*/} @@ -105,7 +78,7 @@ else if(EA.j_ea instanceof J_EAStorageElectric && ((J_EAStorageElectric)EA.j_ea) } /*ALCODEEND*/} -double f_batteryManagementPriceGrid(double currentBatteryStateOfCharge_fr) +double f_batteryManagementPriceGrid() {/*ALCODESTART::1669022533963*/ if (p_batteryAsset.getStorageCapacity_kWh() != 0){ //double willingnessToPayDefault_eurpkWh = 0.3; @@ -141,7 +114,7 @@ else if(EA.j_ea instanceof J_EAStorageElectric && ((J_EAStorageElectric)EA.j_ea) //SOC_setp_fr = (0.5 + 0.4 * Math.cos(2*Math.PI*(energyModel.t_h-18)/24))*(1-3*GN.v_electricityYieldForecast_fr); // Sinusoidal setpoint: aim for high SOC at 18:00h //SOC_setp_fr = 0.6 + 0.25 * Math.sin(2*Math.PI*(main.t_h-12)/24); // Sinusoidal setpoint: aim for low SOC at 6:00h, high SOC at 18:00h. - double SOC_deficit_fr = SOC_setp_fr - currentBatteryStateOfCharge_fr; + double SOC_deficit_fr = SOC_setp_fr - p_batteryAsset.getCurrentStateOfCharge_fr(); // Define WTP price for charging and discharging! // double WTP_charge_eurpkWh = v_electricityPriceLowPassed_eurpkWh - chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC; @@ -166,7 +139,7 @@ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) { } /*ALCODEEND*/} -double f_batteryManagementBalanceGrid(double batterySOC) +double f_batteryManagementBalanceGrid() {/*ALCODESTART::1678114662587*/ if (p_batteryAsset.getStorageCapacity_kWh() != 0){ double currentCoopElectricitySurplus_kW = 0; @@ -228,7 +201,7 @@ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) { double incomingPower_fr = (expectedSolar_kWh + expectedWind_kWh) / p_batteryAsset.getStorageCapacity_kWh(); double SOC_setp_fr = 1 - incomingPower_fr; - chargeSetpoint_kW = FeedbackGain_kWpSOC*(SOC_setp_fr - p_batteryAsset.getCurrentStateOfCharge()); + chargeSetpoint_kW = FeedbackGain_kWpSOC*(SOC_setp_fr - p_batteryAsset.getCurrentStateOfCharge_fr()); } @@ -309,7 +282,7 @@ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) { } /*ALCODEEND*/} -double f_batteryManagementBalanceSupply(double batterySOC) +double f_batteryManagementBalanceSupply() {/*ALCODESTART::1710163119414*/ // Simply tries to prevent exceeding feedin grid capacity, but otherwise aims for an empty battery (so there is always 'absorbtion capacity' available) @@ -342,7 +315,7 @@ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) { double SOC_setp_fr = 0.0; - chargeSetpoint_kW = FeedforwardGain_kWpKw * (currentCoopElectricitySurplus_kW - chargeOffset_kW) + (SOC_setp_fr - batterySOC) * FeedbackGain_kWpSOC; + chargeSetpoint_kW = FeedforwardGain_kWpKw * (currentCoopElectricitySurplus_kW - chargeOffset_kW) + (SOC_setp_fr - p_batteryAsset.getCurrentStateOfCharge_fr()) * FeedbackGain_kWpSOC; chargeSetpoint_kW = min(max(chargeSetpoint_kW, availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging! p_batteryAsset.v_powerFraction_fr = max(-1,min(1, chargeSetpoint_kW / p_batteryAsset.getCapacityElectric_kW())); // Convert to powerFraction and limit power //traceln("Coop surpluss " + currentCoopElectricitySurplus_kW + "kW, Battery charging power " + p_batteryAsset.v_powerFraction_fr*p_batteryAsset.j_ea.getElectricCapacity_kW() + " kW at " + currentBatteryStateOfCharge*100 + " % SOC"); @@ -351,7 +324,7 @@ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) { /*ALCODEEND*/} -double f_batteryManagementBalanceCOOP(double batterySOC) +double f_batteryManagementBalanceCOOP() {/*ALCODESTART::1742557292690*/ if(c_parentCoops.isEmpty()){ @@ -395,23 +368,79 @@ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) { double incomingPower_fr = (expectedSolar_kWh + expectedWind_kWh) / p_batteryAsset.getStorageCapacity_kWh(); double SOC_setp_fr = 1 - incomingPower_fr; - chargeSetpoint_kW = FeedbackGain_kWpSOC*(SOC_setp_fr - p_batteryAsset.getCurrentStateOfCharge()); - chargeSetpoint_kW = min(max(chargeSetpoint_kW, availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging! + chargeSetpoint_kW = FeedbackGain_kWpSOC*(SOC_setp_fr - p_batteryAsset.getCurrentStateOfCharge_fr()); + chargeSetpoint_kW = min(max(chargeSetpoint_kW, -availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging! p_batteryAsset.v_powerFraction_fr = max(-1,min(1, chargeSetpoint_kW / p_batteryAsset.getCapacityElectric_kW())); } } /*ALCODEEND*/} -double f_batteryManagementBas(double currentBatteryStateOfCharge_fr) +double f_batteryManagementBas() {/*ALCODESTART::1746605418870*/ if (p_batteryAsset.getStorageCapacity_kWh() != 0){ double chargeSetpoint_kW = 0; - chargeSetpoint_kW = v_batteryAlgorithmBas.calculateChargeSetpoint_kW(currentBatteryStateOfCharge_fr); // Don't allow too much (dis)charging! + chargeSetpoint_kW = v_batteryAlgorithmBas.calculateChargeSetpoint_kW(p_batteryAsset.getCurrentStateOfCharge_fr()); // Don't allow too much (dis)charging! p_batteryAsset.v_powerFraction_fr = max(-1,min(1, chargeSetpoint_kW / p_batteryAsset.getCapacityElectric_kW())); } /*ALCODEEND*/} +double f_manageBattery_overwrite() +{/*ALCODESTART::1752589957306*/ +if (p_batteryAsset != null) { + if (p_batteryAsset.getStorageCapacity_kWh() > 0 && p_batteryAsset.getCapacityElectric_kW() > 0) { + // We have a battery asset we want to operate, choose the management function that will set the powerfraction + switch (p_batteryOperationMode) { + case OFF: + break; + case SELF_CONSUMPTION: + throw new RuntimeException("current implementation of SELF_CONSUMPTION is not a valid algorithm for GCGridBattery"); + // TODO: Need to write a (or 2) functions for the GCGridBattery that do selfconsumption on the level of gridnode (or coop) + //f_batteryManagementSelfConsumption(); + //break; + case BALANCE: + throw new RuntimeException("BatteryOperationMode Balance is deprecated, please use PEAK_SHAVING_SIMPLE or write your own custom algorithm"); + //f_batteryManagementBalance(); + //break; + case PRICE: + f_batteryManagementPrice(); + break; + case NODAL_PRICING: + throw new RuntimeException("BatteryOperationMode NodalPrice is deprecated, no direct equivalent available. Use PRICE or write your own custom algorithm"); + //f_batteryManagementNodalPricing(); + //break; + case PEAK_SHAVING_SIMPLE: + throw new RuntimeException("current implementation of PEAK_SHAVING_SIMPLE is not a valid algorithm for GCGridBattery"); + //f_batteryManagementPeakShavingSimple(); + //break; + case PEAK_SHAVING_FORECAST: + throw new RuntimeException("current implementation of PEAK_SHAVING_FORECAST is not a valid algorithm for GCGridBattery"); + //f_batteryManagementPeakShavingForecast(); + //break; + case BALANCE_GRID: + f_batteryManagementBalanceGrid(); + break; + case BALANCE_COOP: + f_batteryManagementBalanceCOOP(); + break; + case BALANCE_SUPPLY: + f_batteryManagementBalanceSupply(); + break; + case BATTERY_ALGORITHM_BAS: + f_batteryManagementBas(); + break; + case CUSTOM: + f_batteryManagementCustom(); + break; + default: + throw new RuntimeException("Chosen battery operation mode: " + p_batteryOperationMode.toString() + " unavailable for GridConnection of type: " + this.getClass()); + } + // Now actually operate the asset and update the flows in the GC, f_updateAllFlows will automatically limit the powerFraction between -1 and 1 + p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr); + } +} +/*ALCODEEND*/} + diff --git a/_alp/Agents/GCGridBattery/Code/Functions.xml b/_alp/Agents/GCGridBattery/Code/Functions.xml index ccdca4a2..765225e1 100644 --- a/_alp/Agents/GCGridBattery/Code/Functions.xml +++ b/_alp/Agents/GCGridBattery/Code/Functions.xml @@ -63,6 +63,7 @@ @author: Gillis Hommen @since: 28-12-2022]]> + true 1160 700 @@ -96,10 +93,6 @@ false true true - - - - @@ -158,10 +151,6 @@ false true true - - - - @@ -182,10 +171,6 @@ false true true - - - - @@ -202,10 +187,22 @@ false true true - - - - + + + + VOID + double + 1752589957306 + + 940 + 300 + + false + true + true diff --git a/_alp/Agents/GCGridBattery/Levels/Level.level.xml b/_alp/Agents/GCGridBattery/Levels/Level.level.xml index a95a235e..697d31b3 100644 --- a/_alp/Agents/GCGridBattery/Levels/Level.level.xml +++ b/_alp/Agents/GCGridBattery/Levels/Level.level.xml @@ -64,7 +64,7 @@ 1658477089957 my_dataset -10496 - v_batterySOC_fr + p_batteryAsset != null ? p_batteryAsset.getCurrentStateOfCharge_fr() : 0 true NONE 1.0 @@ -102,7 +102,7 @@ 1724948367410 - + 1450 30 + + 1752588012327 + + 1460 + 680 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 1 + -16777216 + null + SOLID + 430 + 280 + 0.0 + -1 + null + + + 1752588101276 + + 1660 + 690 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 18 + + + CENTER + diff --git a/_alp/Agents/GridConnection/Variables.xml b/_alp/Agents/GridConnection/Variables.xml index b68667f6..e9e7b295 100644 --- a/_alp/Agents/GridConnection/Variables.xml +++ b/_alp/Agents/GridConnection/Variables.xml @@ -207,28 +207,6 @@ - - 1668695288485 - - 1270 - 350 - - false - true - true - - - - - - - 1669725778092 @@ -408,25 +386,6 @@ - - 1678710234329 - - 1270 - 450 - - false - true - true - - - - 1695824940090 @@ -1093,8 +1052,8 @@ 1750763679203 - 970 - 380 + 1540 + 850 - - 1677585426154 - - true - 1270 - 490 - - false - true - true - - - - 1678710234324 @@ -1049,29 +1029,6 @@ - - 1750763679203 - - true - 1540 - 850 - - false - true - true - - - - - - - 1751442438903 @@ -1385,35 +1342,6 @@ - - 1668693418082 - - true - 270 - 140 - - false - true - true - - - NONE - false - - - - - 1668693418080 - TEXT_BOX - 0 - 100 - NO_DELIMETER - - - 1668695364192 @@ -1940,7 +1868,7 @@ true true - + NONE false diff --git a/_alp/Classes/Class.I_BatteryAlgorithm.java b/_alp/Classes/Class.I_BatteryAlgorithm.java deleted file mode 100644 index 335b78be..00000000 --- a/_alp/Classes/Class.I_BatteryAlgorithm.java +++ /dev/null @@ -1,4 +0,0 @@ -public interface I_BatteryAlgorithm -{ -double determineBatteryBehaviour(); -} \ No newline at end of file diff --git a/_alp/Classes/Class.I_BatteryManagement.java b/_alp/Classes/Class.I_BatteryManagement.java new file mode 100644 index 00000000..aab20286 --- /dev/null +++ b/_alp/Classes/Class.I_BatteryManagement.java @@ -0,0 +1,4 @@ +public interface I_BatteryManagement +{ +void manageBattery(); +} \ No newline at end of file diff --git a/_alp/Classes/Class.J_BatteryAlgorithmBas.java b/_alp/Classes/Class.J_BatteryAlgorithmBas.java deleted file mode 100644 index 77bef546..00000000 --- a/_alp/Classes/Class.J_BatteryAlgorithmBas.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * J_BatteryAlgorithmBas - */ -public class J_BatteryAlgorithmBas implements Serializable { - - private GridConnection gc; - /** - * Default constructor - */ - public J_BatteryAlgorithmBas(GridConnection gc) { - this.gc = gc; - } - - - public double calculateChargeSetpoint_kW(){ - - double batteryChargeSetpoint_kW = 0; - - //double currentElectricityPriceEPEX_eurpkWh = energyModel.v_epexForecast_eurpkWh; - - if (gc.p_batteryAsset.getStorageCapacity_kWh() != 0){ - double currentCoopElectricitySurplus_kW = 0; - double CoopConnectionCapacity_kW = 0; - double v_previousPowerBattery_kW = gc.v_previousPowerElectricity_kW;// Assumes battery is only asset on gridconnection!! p_batteryAsset.electricityConsumption_kW-p_batteryAsset.electricityProduction_kW; - if(gc.p_owner != null) { - currentCoopElectricitySurplus_kW = -gc.p_parentNodeElectric.v_currentLoad_kW + v_previousPowerBattery_kW; - CoopConnectionCapacity_kW = 0.9*gc.p_parentNodeElectric.p_capacity_kW; // Use only 90% of capacity for robustness against delay - //} - } else { // Get gridload directly from node - currentCoopElectricitySurplus_kW = -gc.p_parentNodeElectric.v_currentLoad_kW + v_previousPowerBattery_kW; - CoopConnectionCapacity_kW = 0.95*gc.p_parentNodeElectric.p_capacity_kW; // Use only 90% of capacity for robustness against delay - } - - double availableChargePower_kW = CoopConnectionCapacity_kW + currentCoopElectricitySurplus_kW; // Max battery charging power within grid capacity - double availableDischargePower_kW = currentCoopElectricitySurplus_kW - CoopConnectionCapacity_kW; // Max discharging power within grid capacity - double FeedbackGain_kWpSOC = 3 * gc.p_batteryAsset.getCapacityElectric_kW(); // How strongly to aim for SOC setpoint - double FeedforwardGain_kWpKw = 0.1; // Feedforward based on current surpluss in Coop - double chargeOffset_kW = 0; // Charging 'bias', basically increases SOC setpoint slightly during the whole day. - double chargeSetpoint_kW = 0; - //traceln("Test"); - if (availableChargePower_kW < 0) { // prevent congestion - batteryChargeSetpoint_kW = availableChargePower_kW; - return batteryChargeSetpoint_kW; - } - if (gc.energyModel.v_currentSolarPowerNormalized_r > 0.1) { - if (gc.p_parentNodeElectric.v_currentLoad_kW < 0) { - batteryChargeSetpoint_kW = availableChargePower_kW; - return batteryChargeSetpoint_kW; - } - } - else { - double expectedWind_kWh = gc.p_parentNodeElectric.v_totalInstalledWindPower_kW * gc.energyModel.v_WindYieldForecast_fr * gc.energyModel.p_forecastTime_h; - double expectedSolar_kWh = gc.p_parentNodeElectric.v_totalInstalledPVPower_kW * gc.energyModel.v_SolarYieldForecast_fr * gc.energyModel.p_forecastTime_h; - double incomingPower_fr = (expectedSolar_kWh + expectedWind_kWh) / gc.p_batteryAsset.getStorageCapacity_kWh(); - double SOC_setp_fr = 1 - incomingPower_fr; - - chargeSetpoint_kW = FeedbackGain_kWpSOC*(SOC_setp_fr - gc.p_batteryAsset.getCurrentStateOfCharge_fr()); - chargeSetpoint_kW = min(max(chargeSetpoint_kW, availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging! - batteryChargeSetpoint_kW = availableChargePower_kW; - return batteryChargeSetpoint_kW; - } - } - return batteryChargeSetpoint_kW / gc.p_batteryAsset.getCapacityElectric_kW(); - } - - @Override - public String toString() { - return super.toString(); - } - - /** - * This number is here for model snapshot storing purpose
- * It needs to be changed when this class gets changed - */ - private static final long serialVersionUID = 1L; - -} \ No newline at end of file diff --git a/_alp/Classes/Class.J_BatteryPeakShaving.java b/_alp/Classes/Class.J_BatteryManagementPeakShaving.java similarity index 62% rename from _alp/Classes/Class.J_BatteryPeakShaving.java rename to _alp/Classes/Class.J_BatteryManagementPeakShaving.java index c84a2f48..154c721a 100644 --- a/_alp/Classes/Class.J_BatteryPeakShaving.java +++ b/_alp/Classes/Class.J_BatteryManagementPeakShaving.java @@ -1,7 +1,7 @@ /** - * J_BatteryPeakShaving + * J_BatteryManagementPeakShaving */ -public class J_BatteryPeakShaving implements I_BatteryAlgorithm { +public class J_BatteryManagementPeakShaving implements I_BatteryManagement { private GridConnection gc; private Agent target = gc; @@ -14,7 +14,7 @@ public class J_BatteryPeakShaving implements I_BatteryAlgorithm { /** * Default constructor */ - public J_BatteryPeakShaving( GridConnection gc ) { + public J_BatteryManagementPeakShaving( GridConnection gc ) { this.gc = gc; if (gc instanceof GCGridBattery) { target = null; @@ -22,7 +22,7 @@ public J_BatteryPeakShaving( GridConnection gc ) { } } - public J_BatteryPeakShaving( GridConnection gc, double SOC_setpoint_fr, double feedbackGain_fr ) { + public J_BatteryManagementPeakShaving( GridConnection gc, double SOC_setpoint_fr, double feedbackGain_fr ) { this.gc = gc; this.SOC_setpoint_fr = SOC_setpoint_fr; this.feedbackGain_fr = feedbackGain_fr; @@ -36,9 +36,10 @@ public J_BatteryPeakShaving( GridConnection gc, double SOC_setpoint_fr, double f * This algorithm tries to aim for a fixed SOC (0.5 by default) * so that it can take the connection capacity of the GC into account and prevent any peaks when they occur. */ - public double determineBatteryBehaviour() { + public void manageBattery() { if (this.target == null) { - return 0; + gc.p_batteryAsset.f_updateAllFlows(0); + return; } double feedbackGain_kWpSOC = feedbackGain_fr * gc.p_batteryAsset.getCapacityElectric_kW(); double chargeSetpoint_kW = (SOC_setpoint_fr - gc.p_batteryAsset.getCurrentStateOfCharge_fr()) * feedbackGain_kWpSOC; @@ -51,7 +52,7 @@ public double determineBatteryBehaviour() { double availableDischargePower_kW = v_allowedFeedinCapacity_kW + balanceElectricity_kW; // Max discharging power within safety margins chargeSetpoint_kW = min(max(chargeSetpoint_kW, -availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging! - return chargeSetpoint_kW / gc.p_batteryAsset.getCapacityElectric_kW(); + gc.p_batteryAsset.f_updateAllFlows( chargeSetpoint_kW / gc.p_batteryAsset.getCapacityElectric_kW() ); } public void setTarget( Agent agent ) { @@ -90,45 +91,41 @@ public OL_ResultScope getTargetType() { // TODO: Make an interface with at least these 3 functions and make the agents implement it. private double getDeliveryCapacity_kW() { - if (target instanceof GridConnection) { - return gc.v_liveConnectionMetaData.contractedDeliveryCapacity_kW; - } - else if (target instanceof GridNode) { - return ((GridNode)target).p_capacity_kW; - } - else if (target instanceof EnergyCoop) { - return ((EnergyCoop)target).v_liveConnectionMetaData.contractedDeliveryCapacity_kW; - } - else { - throw new RuntimeException("Was not able to find the delivery capacity of the target of the battery in GridConnection: " + gc.p_gridConnectionID); - } + switch (targetType) { + case GRIDCONNECTION: + return gc.v_liveConnectionMetaData.contractedDeliveryCapacity_kW; + case GRIDNODE: + return ((GridNode)target).p_capacity_kW; + case ENERGYCOOP: + return ((EnergyCoop)target).v_liveConnectionMetaData.contractedDeliveryCapacity_kW; + default: + throw new RuntimeException("Was not able to find the delivery capacity of the target of the battery in GridConnection: " + gc.p_gridConnectionID); + } } + private double getFeedinCapacity_kW() { - if (target instanceof GridConnection) { - return gc.v_liveConnectionMetaData.contractedFeedinCapacity_kW; - } - else if (target instanceof GridNode) { - return ((GridNode)target).p_capacity_kW; - } - else if (target instanceof EnergyCoop) { - return ((EnergyCoop)target).v_liveConnectionMetaData.contractedFeedinCapacity_kW; - } - else { - throw new RuntimeException("Was not able to find the feedin capacity of the target of the battery in GridConnection: " + gc.p_gridConnectionID); - } + switch (targetType) { + case GRIDCONNECTION: + return gc.v_liveConnectionMetaData.contractedFeedinCapacity_kW; + case GRIDNODE: + return ((GridNode)target).p_capacity_kW; + case ENERGYCOOP: + return ((EnergyCoop)target).v_liveConnectionMetaData.contractedFeedinCapacity_kW; + default: + throw new RuntimeException("Was not able to find the feedin capacity of the target of the battery in GridConnection: " + gc.p_gridConnectionID); + } } + private double getBalanceElectricity_kW() { - if (target instanceof GridConnection) { - return gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); - } - else if (target instanceof GridNode) { - return ((GridNode)target).v_currentLoad_kW; - } - else if (target instanceof EnergyCoop) { - return ((EnergyCoop)target).fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); - } - else { - throw new RuntimeException("Was not able to find the electricity balance of the target of the battery in GridConnection: " + gc.p_gridConnectionID); + switch (targetType) { + case GRIDCONNECTION: + return gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); + case GRIDNODE: + return ((GridNode)target).v_currentLoad_kW; + case ENERGYCOOP: + return ((EnergyCoop)target).fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); + default: + throw new RuntimeException("Was not able to find the electricity balance of the target of the battery in GridConnection: " + gc.p_gridConnectionID); } } diff --git a/_alp/Classes/Class.J_BatteryPeakShavingForecast.java b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java similarity index 91% rename from _alp/Classes/Class.J_BatteryPeakShavingForecast.java rename to _alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java index 59fae8d6..2f170080 100644 --- a/_alp/Classes/Class.J_BatteryPeakShavingForecast.java +++ b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java @@ -1,27 +1,27 @@ import zeroPackage.ZeroMath; /** - * J_BatteryPeakShavingForecast + * J_BatteryManagementPeakShavingForecast */ -public class J_BatteryPeakShavingForecast implements I_BatteryAlgorithm { +public class J_BatteryManagementPeakShavingForecast implements I_BatteryManagement { private double[] batteryChargingForecast_kW = new double[96]; private GridConnection gc; /** * Default constructor */ - public J_BatteryPeakShavingForecast( GridConnection gc ) { + public J_BatteryManagementPeakShavingForecast( GridConnection gc ) { this.gc = gc; } /** * */ - public double determineBatteryBehaviour() { + public void manageBattery() { int index = roundToInt((gc.energyModel.t_h % 24)/gc.energyModel.p_timeStep_h); if(index == 0){ this.f_peakShavingForecast(); } - return this.batteryChargingForecast_kW[index] / gc.p_batteryAsset.getCapacityElectric_kW(); + gc.p_batteryAsset.f_updateAllFlows( this.batteryChargingForecast_kW[index] / gc.p_batteryAsset.getCapacityElectric_kW() ); } private void f_peakShavingForecast() { diff --git a/_alp/Classes/Class.J_BatteryPrice.java b/_alp/Classes/Class.J_BatteryManagementPrice.java similarity index 88% rename from _alp/Classes/Class.J_BatteryPrice.java rename to _alp/Classes/Class.J_BatteryManagementPrice.java index 110a1ebf..e0b542bd 100644 --- a/_alp/Classes/Class.J_BatteryPrice.java +++ b/_alp/Classes/Class.J_BatteryManagementPrice.java @@ -1,7 +1,7 @@ /** - * J_BatteryPrice + * J_BatteryManagementPrice */ -public class J_BatteryPrice implements I_BatteryAlgorithm { +public class J_BatteryManagementPrice implements I_BatteryManagement { private GridConnection gc; // Parameters used: @@ -17,11 +17,11 @@ public class J_BatteryPrice implements I_BatteryAlgorithm { /** * Default constructor */ - public J_BatteryPrice( GridConnection gc ) { + public J_BatteryManagementPrice( GridConnection gc ) { this.gc = gc; } - public J_BatteryPrice( GridConnection gc, boolean stayWithinConnectionLimits, double chargeDischarge_offset_eurpkWh, double WTPfeedbackGain_eurpSOC, double priceGain_kWhpeur, double priceTimescale_h ) { + public J_BatteryManagementPrice( GridConnection gc, boolean stayWithinConnectionLimits, double chargeDischarge_offset_eurpkWh, double WTPfeedbackGain_eurpSOC, double priceGain_kWhpeur, double priceTimescale_h ) { this.gc = gc; this.stayWithinConnectionLimits = stayWithinConnectionLimits; this.chargeDischarge_offset_eurpkWh = chargeDischarge_offset_eurpkWh; @@ -34,7 +34,7 @@ public J_BatteryPrice( GridConnection gc, boolean stayWithinConnectionLimits, do * This algorithm determines the battery behaviour with the historical national EPEX price. * It has a boolean flag wether or not to take the GC's connection capacity into account. */ - public double determineBatteryBehaviour() { + public void manageBattery() { // Get the national EPEX price double currentElectricityPriceCharge_eurpkWh = gc.energyModel.nationalEnergyMarket.f_getNationalElectricityPrice_eurpMWh()/1000; @@ -64,7 +64,7 @@ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) { chargeSetpoint_kW = min(max(chargeSetpoint_kW, -availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging! } - return chargeSetpoint_kW / gc.p_batteryAsset.getCapacityElectric_kW(); + gc.p_batteryAsset.f_updateAllFlows( chargeSetpoint_kW / gc.p_batteryAsset.getCapacityElectric_kW() ); } @Override diff --git a/_alp/Classes/Class.J_BatterySelfConsumption.java b/_alp/Classes/Class.J_BatteryManagementSelfConsumption.java similarity index 65% rename from _alp/Classes/Class.J_BatterySelfConsumption.java rename to _alp/Classes/Class.J_BatteryManagementSelfConsumption.java index 653ad93b..8bd32f86 100644 --- a/_alp/Classes/Class.J_BatterySelfConsumption.java +++ b/_alp/Classes/Class.J_BatteryManagementSelfConsumption.java @@ -1,14 +1,14 @@ /** - * J_BatterySelfConsumption + * J_BatteryManagementSelfConsumption */ -public class J_BatterySelfConsumption implements I_BatteryAlgorithm { +public class J_BatteryManagementSelfConsumption implements I_BatteryManagement { private GridConnection gc; /** * Default constructor */ - public J_BatterySelfConsumption( GridConnection gc ) { + public J_BatteryManagementSelfConsumption( GridConnection gc ) { this.gc = gc; } @@ -18,8 +18,8 @@ public J_BatterySelfConsumption( GridConnection gc ) { * If there is overproduction and room in the battery it will charge. * If there is more consumption than production it will discharge the battery to make up for the difference untill the battery is empty. */ - public double determineBatteryBehaviour() { - return gc.p_batteryAsset.v_powerFraction_fr = -gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) / gc.p_batteryAsset.getCapacityElectric_kW(); + public void manageBattery() { + gc.p_batteryAsset.f_updateAllFlows( -gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) / gc.p_batteryAsset.getCapacityElectric_kW() ); } @Override From 061870df840c586d4863b81bed1455aabf11ab84 Mon Sep 17 00:00:00 2001 From: Luc-Sol Date: Tue, 22 Jul 2025 10:12:58 +0200 Subject: [PATCH 4/6] Added J_BatteryManagementOff --- Zero_engine.alpx | 9 ++ .../Agents/GCNeighborhood/Code/Functions.java | 109 ------------------ _alp/Agents/GCNeighborhood/Code/Functions.xml | 34 ------ .../Classes/Class.J_BatteryManagementOff.java | 30 +++++ 4 files changed, 39 insertions(+), 143 deletions(-) create mode 100644 _alp/Classes/Class.J_BatteryManagementOff.java diff --git a/Zero_engine.alpx b/Zero_engine.alpx index 17b9bdf8..cb073a63 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -962,6 +962,10 @@ 1668693527446 +