diff --git a/Zero_engine.alpx b/Zero_engine.alpx
index b5e55d46..cb073a63 100644
--- a/Zero_engine.alpx
+++ b/Zero_engine.alpx
@@ -963,44 +963,36 @@
1668693527446
-
-
@@ -1281,7 +1273,44 @@
-
+
+
+ 1752677823817
+
+
+
+ 1752677826356
+
+
+
+ 1752677829820
+
+
+
+ 1752677832758
+
+
+
+ 1752679379816
+
+
+
+ 1752680962144
+
+
+
+ 1752681631114
+
+
+
+ 1752681639768
+
+
+
+ 1752737189062
+
+
+
EULER
RK45_NEWTON
@@ -1357,120 +1386,148 @@
1659091451342
+ 1752677832758
1659091479591
+ 1752677832758
1659091488030
+ 1752677832758
1659104834899
+ 1752677832758
1659108919926
+ 1752677832758
1659117174456
+ 1752677832758
1659117174457
true
+ 1752677832758
1659117174458
+ 1752677832758
1659446215929
+ 1752677832758
1659446215929
+ 1752677832758
1659447107390
+ 1752677832758
1659447107391
+ 1752677832758
1659513814164
+ 1752677832758
1659534704067
+ 1752677832758
1660131551684
+ 1752677832758
1661266990567
true
+ 1752737189062
1661349111073
true
+ 1752737189062
1663238817163
+ 1752680962144
1665502017804
+ 1752677832758
1666189454452
+ 1752677832758
1666189454453
true
+ 1752677832758
1666879973864
true
+ 1752737189062
1666879973865
true
+ 1752737189062
1668600448637
+ 1752677832758
1671107396262
+ 1752677832758
1671522756085
+ 1752677832758
1673445448881
+ 1752677832758
1673445438882
+ 1752680962144
1673445448882
@@ -1487,47 +1544,58 @@
1673445448885
+ 1752680962144
1678469210821
true
+ 1752677832758
1692861398767
+ 1752681639768
1692862190945
+ 1752681639768
1692862773194
+ 1752677832758
1692876125447
+ 1752681639768
1707991094535
+ 1752677832758
1707992650964
+ 1752677832758
1711009967838
+ 1752677832758
1715862850276
+ 1752680962144
1726148464063
+ 1752680962144
1727774738469
@@ -1541,23 +1609,28 @@
1729171686537
true
+ 1752737189062
1729262288167
+ 1752679379816
1729510354900
+ 1752679379816
1729586334721
true
+ 1752737189062
1731483284975
+ 1752679379816
1737025326025
@@ -1566,14 +1639,17 @@
1737633433233
+ 1752677832758
1740048926477
+ 1752679379816
1740048926478
+ 1752679379816
1741163937278
@@ -1582,26 +1658,27 @@
1741180550081
+ 1752680962144
1741180880935
+ 1752680962144
1741361867834
+ 1752680962144
1741864496371
-
-
- 1746606645736
-
+ 1752680962144
1749648342034
+ 1752677832758
1749649002419
@@ -1610,6 +1687,37 @@
1749651263461
+ 1752677832758
+
+
+ 1752677257516
+
+ 1752677826356
+
+
+ 1752677992581
+
+ 1752677826356
+
+
+ 1752678003039
+
+ 1752677826356
+
+
+ 1752678015847
+
+ 1752677826356
+
+
+ 1752678031327
+
+ 1752677826356
+
+
+ 1753169766770
+
+ 1752677826356
diff --git a/_alp/Agents/A_SubTenant/AOC.A_SubTenant.xml b/_alp/Agents/A_SubTenant/AOC.A_SubTenant.xml
index b0569e05..42791de0 100644
--- a/_alp/Agents/A_SubTenant/AOC.A_SubTenant.xml
+++ b/_alp/Agents/A_SubTenant/AOC.A_SubTenant.xml
@@ -2,6 +2,8 @@
1658752695711
+ true
+ 1752737189062
zero_engine
Actor
diff --git a/_alp/Agents/Actor/AOC.Actor.xml b/_alp/Agents/Actor/AOC.Actor.xml
index 25914454..91fd085a 100644
--- a/_alp/Agents/Actor/AOC.Actor.xml
+++ b/_alp/Agents/Actor/AOC.Actor.xml
@@ -2,6 +2,7 @@
1674662535386
+ 1752677829820
false
1674662535384
diff --git a/_alp/Agents/ConnectionOwner/AOC.ConnectionOwner.xml b/_alp/Agents/ConnectionOwner/AOC.ConnectionOwner.xml
index c7c40b96..352501dd 100644
--- a/_alp/Agents/ConnectionOwner/AOC.ConnectionOwner.xml
+++ b/_alp/Agents/ConnectionOwner/AOC.ConnectionOwner.xml
@@ -2,6 +2,7 @@
1660224852394
+ 1752677829820
zero_engine
diff --git a/_alp/Agents/ConnectionOwner/Variables.xml b/_alp/Agents/ConnectionOwner/Variables.xml
index 95dec139..31721350 100644
--- a/_alp/Agents/ConnectionOwner/Variables.xml
+++ b/_alp/Agents/ConnectionOwner/Variables.xml
@@ -1651,6 +1651,7 @@
1704196760553
+ true
60
440
-
- 1746606592165
-
- 1160
- 800
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
-
-
-
1732029220158
diff --git a/_alp/Agents/GCHouse/AOC.GCHouse.xml b/_alp/Agents/GCHouse/AOC.GCHouse.xml
index 1fac8e85..5834fb49 100644
--- a/_alp/Agents/GCHouse/AOC.GCHouse.xml
+++ b/_alp/Agents/GCHouse/AOC.GCHouse.xml
@@ -3,6 +3,7 @@
1663772408667
+ 1752677823817
zero_engine
GridConnection
@@ -38,9 +39,6 @@
-
-
-
@@ -104,6 +102,9 @@
+
+
+
false
diff --git a/_alp/Agents/GCHouse/Code/AdditionalClassCode.java b/_alp/Agents/GCHouse/Code/AdditionalClassCode.java
index 5667ec32..e6c07d58 100644
--- a/_alp/Agents/GCHouse/Code/AdditionalClassCode.java
+++ b/_alp/Agents/GCHouse/Code/AdditionalClassCode.java
@@ -35,11 +35,6 @@ public void f_chargeOnPrice(double a, double b){
f_chargeOnPrice_overwrite(a,b);
}*/
-@Override
-public void f_batteryManagementPrice(double currentBatteryStateOfCharge) {
- f_batteryManagementPrice_overwrite(currentBatteryStateOfCharge);
-}
-
@Override
public void f_simpleCharging(){
f_simpleCharging_overwrite();
diff --git a/_alp/Agents/GCHouse/Code/Functions.java b/_alp/Agents/GCHouse/Code/Functions.java
index b5acecf4..8c4a9ed8 100644
--- a/_alp/Agents/GCHouse/Code/Functions.java
+++ b/_alp/Agents/GCHouse/Code/Functions.java
@@ -94,28 +94,7 @@
*/
f_manageChargers();
-
-v_currentLoadLowPassed_kW += v_lowPassFactorLoad_fr * ( fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_currentLoadLowPassed_kW );
-
-if ( p_batteryAsset != null ) {
- if ( p_batteryAsset.getStorageCapacity_kWh() != 0.0) {
- v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge();
- if( p_batteryOperationMode == OL_BatteryOperationMode.HOUSEHOLD_LOAD){
- 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);
- } else if (p_batteryOperationMode == OL_BatteryOperationMode.SELF_CONSUMPTION){
- f_batteryManagementSelfConsumption();
- }
- p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr);
- v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge();
- }
-}
-
+f_manageBattery();
/*ALCODEEND*/}
double f_connectToChild_overwrite(Agent ConnectingParentNode)
@@ -455,7 +434,7 @@ else if (lastLoopsPriceLevel.equals("low") && powerAvailableAtLastLoop_kW > p_mi
double availableCapacityFromBatteries = p_batteryAsset == null ? 0 : p_batteryAsset.getCapacityAvailable_kW();
//double availableChargingCapacity = v_allowedCapacity_kW + availableCapacityFromBatteries - v_currentPowerElectricity_kW;
double availableChargingCapacity = v_liveConnectionMetaData.contractedDeliveryCapacity_kW + availableCapacityFromBatteries - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY);
-v_vehicleSOC_fr = p_householdEV.getCurrentStateOfCharge();
+v_vehicleSOC_fr = p_householdEV.getCurrentStateOfCharge_fr();
switch (p_chargingAttitudeVehicles) {
case SIMPLE:
@@ -479,7 +458,7 @@ else if (lastLoopsPriceLevel.equals("low") && powerAvailableAtLastLoop_kW > p_mi
{/*ALCODESTART::1675033218897*/
double powerFraction_fr = 0;
-if( p_householdEV.getCurrentStateOfCharge() < 1 ) {
+if( p_householdEV.getCurrentStateOfCharge_fr() < 1 ) {
powerFraction_fr = 1;
/*if ( p_hasSmartFlexAssets ){
ConnectionOwner owner = ((ConnectionOwner)l_ownerActor.getConnectedAgent());
@@ -739,70 +718,6 @@ else if ( v_batterySOC_fr < 0.6 && v_currentPowerElectricity_kW < 1 && v_current
/*ALCODEEND*/}
-double f_batteryManagementPrice_overwrite(double currentBatteryStateOfCharge)
-{/*ALCODESTART::1678709047802*/
-if (p_batteryAsset.getStorageCapacity_kWh() != 0){
- //double willingnessToPayDefault_eurpkWh = 0.3;
- double chargeDischarge_offset_eurpkWh = 0.0;
- double WTPfeedbackGain_eurpSOC = 0.25; // When SOC-error is 100%, adjust WTP price by 1 eurpkWh
- double priceGain = 2; // How strongly to ramp up power with price-delta's
- //double congestionTariffCoop_eurpkWh = -(((ConnectionOwner)p_ownerActor).p_CoopParent.v_electricitySurplus_kW + v_previousPowerElectricity_kW)/1200*0.1;
-
- double chargeSetpoint_kW = 0;
-
- if(p_owner != null) {
- //traceln("Initial Mappings are: " + ((ConnectionOwner)p_ownerActor).v_currentPriceBands);
- double currentElectricityPriceCharge_eurpkWh = p_owner.f_getElectricityPrice(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) + 10.0); // query price at 100kW charging
- double currentElectricityPriceDischarge_eurpkWh = p_owner.f_getElectricityPrice(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - 10.0); // query price at -100kW charging
- //double lowPassFraction = min(1,1*1.2*energyModel.p_timeStep_h); // smaller value results in more filtering
- //v_electricityPriceLowPassed_eurpkWh += v_lowPassFactor_fr * ( currentElectricityPriceCharge_eurpkWh - v_electricityPriceLowPassed_eurpkWh );
-
- //double currentPricePowerBandPos_kW = ownerActor.v_priceBandsDelivery.ceilingKey(10.0); // Up to what power does this price hold?
- //double currentPricePowerBandNeg_kW = ownerActor.v_priceBandsDelivery.floorKey(10.0); // Down to what power does this price hold?
-
- double SOC_setp_fr = 0.5;
- //traceln("Current price is " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, between " + currentPricePowerBandNeg_kW + " kW and " + currentPricePowerBandPos_kW + " kW");
- if (!c_vehicleAssets.isEmpty()) {
- SOC_setp_fr = 0.5 + 0.25 * Math.sin(2*Math.PI*(energyModel.t_h-12)/24); // Sinusoidal setpoint: aim for low SOC at 6:00h, high SOC at 18:00h.
- } else if (energyModel.v_liveAssetsMetaData.totalInstalledWindPower_kW > 0 ) {
- SOC_setp_fr = 0.9 - 0.8 * energyModel.v_WindYieldForecast_fr;
- //traceln("Forecast-based SOC setpoint: " + SOC_setp_fr + " %");
- }
- double SOC_deficit_fr = SOC_setp_fr - currentBatteryStateOfCharge; // How far away from desired SOC? SOC too LOW is a POSITIVE deficit
-
- // Define WTP price for charging and discharging!
- double WTP_charge_eurpkWh = v_electricityPriceLowPassed_eurpkWh - chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
- double WTP_discharge_eurpkWh = v_electricityPriceLowPassed_eurpkWh + chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
-
- //traceln("WTP charge is " + WTP_charge_eurpkWh + " eurpkWh, discharge is " + WTP_discharge_eurpkWh + " eurpkWh");
- // Choose charging power based on prices and desired SOC level
- if ( WTP_charge_eurpkWh > currentElectricityPriceCharge_eurpkWh ) { // if willingness to pay higher than current electricity price
- //chargeSetpoint_kW = min(p_batteryAsset.getElectricCapacity_kW()*(WTP_charge_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain, currentPricePowerBandPos_kW) ;
- chargeSetpoint_kW = p_batteryAsset.getCapacityElectric_kW()*(WTP_charge_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain;
- //traceln("WTP charge " + WTP_charge_eurpkWh + " eurpkWh is high than electricity price " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, so charge!") ;
- } else if (WTP_discharge_eurpkWh < currentElectricityPriceDischarge_eurpkWh) {
- //chargeSetpoint_kW = -min(p_batteryAsset.getElectricCapacity_kW()*(currentElectricityPriceDischarge_eurpkWh - WTP_discharge_eurpkWh)*priceGain, currentPricePowerBandPos_kW);
- chargeSetpoint_kW = -p_batteryAsset.getCapacityElectric_kW()*(currentElectricityPriceDischarge_eurpkWh - WTP_discharge_eurpkWh)*priceGain;
- //traceln("WTP discharge " + WTP_discharge_eurpkWh + " eurpkWh is lower than electricity price " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, so discharge!") ;
- }
-
- // limit charging power to available connection capacity
- boolean b_stayWithinConnectionLimits = true;
- if( b_stayWithinConnectionLimits ) {
-
- double electricitySurplus_kW = - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY);
-
- double availableChargePower_kW = electricitySurplus_kW + v_liveConnectionMetaData.contractedDeliveryCapacity_kW; // Max battery charging power within grid capacity
- double availableDischargePower_kW = electricitySurplus_kW - v_liveConnectionMetaData.contractedFeedinCapacity_kW; // Max discharging power within grid capacity
- 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
- }
- p_batteryAsset.f_updateAllFlows( p_batteryAsset.v_powerFraction_fr );
-}
-/*ALCODEEND*/}
-
double f_connectTo_J_EA_House(J_EA j_ea)
{/*ALCODESTART::1693300820997*/
if (j_ea instanceof J_EAConversion) {
diff --git a/_alp/Agents/GCHouse/Code/Functions.xml b/_alp/Agents/GCHouse/Code/Functions.xml
index c04bd689..dd5b575a 100644
--- a/_alp/Agents/GCHouse/Code/Functions.xml
+++ b/_alp/Agents/GCHouse/Code/Functions.xml
@@ -215,26 +215,6 @@
true
-
- VOID
- double
- 1678709047802
-
- 920
- 300
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
-
-
VOID
double
diff --git a/_alp/Agents/GCHouse/Levels/Level.level.xml b/_alp/Agents/GCHouse/Levels/Level.level.xml
index 8e8b7b48..4c2bbbb9 100644
--- a/_alp/Agents/GCHouse/Levels/Level.level.xml
+++ b/_alp/Agents/GCHouse/Levels/Level.level.xml
@@ -105,7 +105,7 @@
1726301549553
-
+
1560
30
diff --git a/_alp/Agents/GCIndustry/AOC.GCIndustry.xml b/_alp/Agents/GCIndustry/AOC.GCIndustry.xml
index f0193bcc..d16f4f0e 100644
--- a/_alp/Agents/GCIndustry/AOC.GCIndustry.xml
+++ b/_alp/Agents/GCIndustry/AOC.GCIndustry.xml
@@ -2,7 +2,9 @@
1665480522864
+ true
+ 1752737189062
zero_engine
GridConnection
@@ -38,9 +40,6 @@
-
-
-
@@ -104,6 +103,9 @@
+
+
+
false
diff --git a/_alp/Agents/GCIndustry/Code/Functions.java b/_alp/Agents/GCIndustry/Code/Functions.java
index 898e3765..fb1c07ba 100644
--- a/_alp/Agents/GCIndustry/Code/Functions.java
+++ b/_alp/Agents/GCIndustry/Code/Functions.java
@@ -133,8 +133,8 @@ else if( ea.p_energyAssetType == OL_EnergyAssetType.HEAT_DEMAND ) {
if (p_batteryAsset != null){ // TEST CODE
if (p_batteryAsset.getStorageCapacity_kWh() > 0) {
//f_batteryManagementBalance(p_batteryAsset.getCurrentStateOfCharge());
- f_batteryManagementNodalPricing(p_batteryAsset.getCurrentStateOfCharge());
- p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr);
+ f_batteryManagementNodalPricing();
+ p_batteryAsset.f_updateAllFlows();
//J_FlowsMap flowsMap = flowsPair.getFirst();
//traceln("flows:" + Arrays.toString(arr));
//v_batteryPowerElectric_kW = flowsMap.get(OL_EnergyCarriers.ELECTRICITY);
@@ -181,7 +181,7 @@ else if( ea.p_energyAssetType == OL_EnergyAssetType.HEAT_DEMAND ) {
double HP_COP = ((J_EAConversionHeatPump)p_primaryHeatingAsset).getCOP();
double HP_powerDemand_kW = heatDemand_kW / HP_COP;
// Decide to use CHP or HeatPump to fulfill heat demand based on 'SoC' of gasbuffer and current electricity use on site
- if ( (-(fm_currentConsumptionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - fm_currentProductionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)) > 0.5*v_liveConnectionMetaData.contractedFeedinCapacity_kW*2*(p_gasBuffer.getCurrentStateOfCharge()-0.5) | p_gasBuffer.getCurrentStateOfCharge() < 0.05) & p_gasBuffer.getCurrentStateOfCharge() < 0.9) { // Use heatpump when it can be done selfsufficiently or when methane supply is zero
+ if ( (-(fm_currentConsumptionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - fm_currentProductionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)) > 0.5*v_liveConnectionMetaData.contractedFeedinCapacity_kW*2*(p_gasBuffer.getCurrentStateOfCharge_fr()-0.5) | p_gasBuffer.getCurrentStateOfCharge_fr() < 0.05) & p_gasBuffer.getCurrentStateOfCharge_fr() < 0.9) { // Use heatpump when it can be done selfsufficiently or when methane supply is zero
//traceln("HeatPump in operation with COP " + HP_COP);
p_secondaryHeatingAsset.v_powerFraction_fr = 0;
p_primaryHeatingAsset.v_powerFraction_fr = min(1,HP_powerDemand_kW / p_primaryHeatingAsset.getInputCapacity_kW());
@@ -193,14 +193,14 @@ else if( ea.p_energyAssetType == OL_EnergyAssetType.HEAT_DEMAND ) {
p_primaryHeatingAsset.v_powerFraction_fr = max(0,min(1,(heatDemand_kW-p_secondaryHeatingAsset.v_powerFraction_fr*p_secondaryHeatingAsset.getOutputCapacity_kW()) / p_primaryHeatingAsset.getOutputCapacity_kW())); // Let gas burner fill the heatdemandgap
}
} else if ( p_primaryHeatingAsset instanceof J_EAConversionGasCHP & p_secondaryHeatingAsset instanceof J_EAConversionGasBurner) { // CHP & gas burner
- if ( p_gasBuffer.getCurrentStateOfCharge() < 0.05) { // Use regular gas burner when biogas buffer is nearly empty
+ if ( p_gasBuffer.getCurrentStateOfCharge_fr() < 0.05) { // Use regular gas burner when biogas buffer is nearly empty
// if ( (-v_currentPowerElectricity_kW > 0.5*p_connectionCapacity_kW*2*(p_gasBuffer.j_ea.getCurrentStateOfCharge()-0.5) | p_gasBuffer.j_ea.getCurrentStateOfCharge() < 0.05) & p_gasBuffer.j_ea.getCurrentStateOfCharge() < 0.9) { // Use gas burner when biogas is depleted or when there is too much PV and CHP would lead to curtailment
//traceln("HeatPump in operation with COP " + HP_COP);
p_primaryHeatingAsset.v_powerFraction_fr = 0;
p_secondaryHeatingAsset.v_powerFraction_fr = min(1,heatDemand_kW / p_secondaryHeatingAsset.getOutputCapacity_kW());
} else { // CHP when there is sufficient biogas
//traceln("CHP capacityHeat_kW: " + p_primaryHeatingAsset.j_ea.getHeatCapacity_kW());
- if ( p_gasBuffer.getCurrentStateOfCharge() < 0.9 ) { // Biogas tank not full, allow reduced CHP power when it prevents curtailment.
+ if ( p_gasBuffer.getCurrentStateOfCharge_fr() < 0.9 ) { // Biogas tank not full, allow reduced CHP power when it prevents curtailment.
p_primaryHeatingAsset.v_powerFraction_fr = min(min(1,heatDemand_kW / p_primaryHeatingAsset.getOutputCapacity_kW()),(v_liveConnectionMetaData.contractedFeedinCapacity_kW + (fm_currentConsumptionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - fm_currentProductionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY))) / p_primaryHeatingAsset.getInputCapacity_kW());
} else {
p_primaryHeatingAsset.v_powerFraction_fr = min(1,heatDemand_kW / p_primaryHeatingAsset.getOutputCapacity_kW());
diff --git a/_alp/Agents/GCNeighborhood/AOC.GCNeighborhood.xml b/_alp/Agents/GCNeighborhood/AOC.GCNeighborhood.xml
index f36ee5df..3be9e6b4 100644
--- a/_alp/Agents/GCNeighborhood/AOC.GCNeighborhood.xml
+++ b/_alp/Agents/GCNeighborhood/AOC.GCNeighborhood.xml
@@ -3,6 +3,7 @@
1718724980083
+ 1752677823817
zero_engine
GridConnection
@@ -41,9 +42,6 @@
-
-
-
@@ -104,6 +102,9 @@
+
+
+
false
diff --git a/_alp/Agents/GCNeighborhood/Code/Functions.java b/_alp/Agents/GCNeighborhood/Code/Functions.java
index aca6c9db..30634c73 100644
--- a/_alp/Agents/GCNeighborhood/Code/Functions.java
+++ b/_alp/Agents/GCNeighborhood/Code/Functions.java
@@ -9,28 +9,7 @@
v_lowPassFactorLoad_fr = 0.003; // Vastgezet voor de NBHs
v_currentLoadLowPassed_kW += v_lowPassFactorLoad_fr * ( fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_currentLoadLowPassed_kW ); //you want to do determine the lowpassLoad BEFORE the using the battery. As this behavior of the battery should nog be dependent on the load of the battery in the previous timesteps
-//Battery
-if( p_batteryAsset != null && p_batteryAsset.getStorageCapacity_kWh() != 0 && p_batteryOperationMode != OL_BatteryOperationMode.OFF){
- switch (p_batteryOperationMode){
- case BALANCE:
- if(p_ignoreGridCapacityBattery){
- f_batteryManagementBalanceNoGCCapacity_NBH(v_batterySOC_fr);
- }
- else{
- f_batteryManagementBalance_NBH(v_batterySOC_fr);
- }
- break;
- case PRICE:
- f_batteryManagementPrice_NBH(v_batterySOC_fr);
- break;
- default:
- break;
- }
- p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr);
- v_batteryPowerElectric_kW = p_batteryAsset.getLastFlows().get(OL_EnergyCarriers.ELECTRICITY);
- v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge();
-}
-
+f_manageBattery();
/*ALCODEEND*/}
double f_setHeatingMethodPct_services(double[] pctArray)
@@ -487,115 +466,6 @@ else if(((J_EAConversionHeatPump)j_ea).getAmbientTempType() == OL_AmbientTempTyp
/*ALCODEEND*/}
-double f_batteryManagementBalance_NBH(double batterySOC)
-{/*ALCODESTART::1730897215443*/
-//traceln("Battery storage capacity: " + ((J_EAStorageElectric)p_batteryAsset.j_ea).getStorageCapacity_kWh());
-if (p_batteryAsset.getStorageCapacity_kWh() != 0){
- double currentLoadDeviation_kW = fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_currentLoadLowPassed_kW; // still excludes battery power
- //traceln("electricitySuprlus_kW: " + electricitySurplus_kW);
- //v_electricityPriceLowPassed_eurpkWh += v_lowPassFactor_fr * ( electricitySurplus_kW - v_electricityPriceLowPassed_eurpkWh );
- double v_allowedDeliveryCapacity_kW = v_liveConnectionMetaData.contractedDeliveryCapacity_kW*0.95;
- double v_allowedFeedinCapacity_kW = v_liveConnectionMetaData.contractedFeedinCapacity_kW*0.95;
- //double connectionCapacity_kW = v_allowedCapacity_kW; // Use only 90% of capacity for robustness against delay
- double availableChargePower_kW = v_allowedDeliveryCapacity_kW - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); // Max battery charging power within grid capacity
- double availableDischargePower_kW = fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) + v_allowedFeedinCapacity_kW; // Max discharging power within grid capacity
-
- double SOC_setp_fr_offset = v_SOC_setp_fr_offset_balance; // default: 0.6
- //TODO: Verander in iets specifieks voor project - overwrite in GC Neighborhood
- //traceln("Current price is " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, between " + currentPricePowerBandNeg_kW + " kW and " + currentPricePowerBandPos_kW + " kW");
- //SOC_setp_fr = 0.6 + 0.25 * Math.cos(2*Math.PI*(energyModel.t_h-18)/24); // Sinusoidal setpoint: aim for low SOC at 6:00h, high SOC at 18:00h.
-
- //TODO forecast keer installed cap per buurt genormaliseerd.
- double windEnergyExpectedNormalized_fr = energyModel.v_WindYieldForecast_fr * energyModel.p_forecastTime_h * v_liveAssetsMetaData.totalInstalledWindPower_kW / p_batteryAsset.getStorageCapacity_kWh();
- double solarEnergyExpectedNormalized_fr = energyModel.v_SolarYieldForecast_fr * energyModel.p_forecastTime_h * v_liveAssetsMetaData.totalInstalledPVPower_kW / p_batteryAsset.getStorageCapacity_kWh();
- //double heatpumpExpectedEnergyDrawNormalized_fr = ...
- double SOC_setp_fr = SOC_setp_fr_offset + 0.1 * Math.cos(2*Math.PI*(energyModel.t_h-7)/24) - 0.1 * windEnergyExpectedNormalized_fr - 0.1 * solarEnergyExpectedNormalized_fr;
- //traceln("Forecast-based SOC setpoint: " + SOC_setp_fr + " %");
-
- //traceln("SOC_setp_fr" + SOC_setp_fr);
-
- //traceln("SOC setpoint at " + getHourOfDay() + " h is " + SOC_setp_fr*100 + "%");
- double FeedbackGain_kWpSOC_factor = v_FeedbackGain_kWpSOC_factor_balance; // default: 0.4
- double FeedbackGain_kWpSOC = FeedbackGain_kWpSOC_factor * p_batteryAsset.getCapacityElectric_kW(); // How strongly to aim for SOC setpoint
- double FeedforwardGain_kWpKw = 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 * currentLoadDeviation_kW + (SOC_setp_fr - batterySOC) * 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("v_powerFraction_fr" + p_batteryAsset.v_powerFraction_fr);
- //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");
-}
-/*ALCODEEND*/}
-
-double f_batteryManagementPrice_NBH(double currentBatteryStateOfCharge)
-{/*ALCODESTART::1730897215446*/
-if (p_batteryAsset.getStorageCapacity_kWh() != 0){
- //double willingnessToPayDefault_eurpkWh = 0.3;
- double chargeDischarge_offset_eurpkWh = 0.0;
- double WTPfeedbackGain_eurpSOC = 0.5; //Gelijk aan de gem marktprijs - When SOC-error is 100%, adjust WTP price by 1 eurpkWh
- double priceGain_kWhpeur = v_priceGain_kWhpeur; // default: 2; // How strongly to ramp up power with price-delta's
- //double congestionTariffCoop_eurpkWh = -(((ConnectionOwner)p_ownerActor).p_CoopParent.v_electricitySurplus_kW + v_previousPowerElectricity_kW)/1200*0.1;
-
- double chargeSetpoint_kW = 0;
-
- //if(l_ownerActor.getConnectedAgent() instanceof ConnectionOwner) {
- //ConnectionOwner ownerActor = (ConnectionOwner)l_ownerActor.getConnectedAgent();
- //traceln("Initial Mappings are: " + ((ConnectionOwner)p_ownerActor).v_currentPriceBands);
- double currentElectricityPriceCharge_eurpkWh = energyModel.nationalEnergyMarket.f_getNationalElectricityPrice_eurpMWh()/1000;//double lowPassFraction = min(1,1*1.2*energyModel.p_timeStep_h); // smaller value results in more filtering
-
- v_electricityPriceLowPassed_eurpkWh += v_lowPassFactor_fr * ( currentElectricityPriceCharge_eurpkWh - v_electricityPriceLowPassed_eurpkWh );
-
- //double currentPricePowerBandPos_kW = ownerActor.v_priceBandsDelivery.ceilingKey(100.0); // Up to what power does this price hold?
- //double currentPricePowerBandNeg_kW = ownerActor.v_priceBandsDelivery.floorKey(100.0); // Down to what power does this price hold?
-
- double SOC_setp_fr = v_SOC_setp_fr_price; // Default: 0.5
- //traceln("Current price is " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, between " + currentPricePowerBandNeg_kW + " kW and " + currentPricePowerBandPos_kW + " kW");
- /*if (!c_vehicleAssets.isEmpty()) {
- SOC_setp_fr = 0.5 + 0.25 * Math.sin(2*Math.PI*(energyModel.t_h-12)/24); // Sinusoidal setpoint: aim for low SOC at 6:00h, high SOC at 18:00h.
- } else if (energyModel.v_totalInstalledWindPower_kW > 0 ) {
- SOC_setp_fr = 0.9 - 0.8 * energyModel.v_WindYieldForecast_fr;
- //traceln("Forecast-based SOC setpoint: " + SOC_setp_fr + " %");
- }*/
- double SOC_deficit_fr = SOC_setp_fr - currentBatteryStateOfCharge; // How far away from desired SOC? SOC too LOW is a POSITIVE deficit
-
- // Define WTP price for charging and discharging!
- double WTP_charge_eurpkWh = v_electricityPriceLowPassed_eurpkWh - chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
- double WTP_discharge_eurpkWh = v_electricityPriceLowPassed_eurpkWh + chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
-
- //traceln("WTP charge is " + WTP_charge_eurpkWh + " eurpkWh, discharge is " + WTP_discharge_eurpkWh + " eurpkWh");
- // Choose charging power based on prices and desired SOC level
- if ( WTP_charge_eurpkWh > currentElectricityPriceCharge_eurpkWh ) { // if willingness to pay higher than current electricity price
- //chargeSetpoint_kW = min(p_batteryAsset.getElectricCapacity_kW()*(WTP_charge_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain, currentPricePowerBandPos_kW) ;
- chargeSetpoint_kW = p_batteryAsset.getCapacityElectric_kW()*(WTP_charge_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain_kWhpeur;
- //traceln("WTP charge " + WTP_charge_eurpkWh + " eurpkWh is high than electricity price " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, so charge!") ;
- } else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) {
- //chargeSetpoint_kW = -min(p_batteryAsset.getElectricCapacity_kW()*(currentElectricityPriceDischarge_eurpkWh - WTP_discharge_eurpkWh)*priceGain, currentPricePowerBandPos_kW);
- chargeSetpoint_kW = -p_batteryAsset.getCapacityElectric_kW()*(currentElectricityPriceCharge_eurpkWh - WTP_discharge_eurpkWh)*priceGain_kWhpeur;
- //traceln("WTP discharge " + WTP_discharge_eurpkWh + " eurpkWh is lower than electricity price " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, so discharge!") ;
- }
-
- // limit charging power to available connection capacity
- boolean b_stayWithinConnectionLimits = true;
- if( b_stayWithinConnectionLimits ) {
-
- double availableChargePower_kW = v_liveConnectionMetaData.contractedDeliveryCapacity_kW - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); // Max battery charging power within grid capacity
- double availableDischargePower_kW = v_liveConnectionMetaData.contractedFeedinCapacity_kW + fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); // Max discharging power within grid capacity
- 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
-
- //double chargedPower_kW = max(0,p_batteryAsset.v_powerFraction_fr*p_batteryAsset.getCapacityElectric_kW());
- //double dischargedPower_kW = min(0,p_batteryAsset.v_powerFraction_fr*p_batteryAsset.getCapacityElectric_kW());
-
- v_batteryMoneyMade_euro += -p_batteryAsset.v_powerFraction_fr*p_batteryAsset.getCapacityElectric_kW()*energyModel.p_timeStep_h*energyModel.v_epexForecast_eurpkWh;
- //}
-
-}
-
-/*ALCODEEND*/}
-
double f_setH2HeatingFr_industry(double amountOfHydrogenUseForHeating_fr)
{/*ALCODESTART::1732550952237*/
@@ -645,9 +515,10 @@ else if(((J_EAConversionHeatPump)j_ea).getAmbientTempType() == OL_AmbientTempTyp
double f_resetSpecificGCStates_override()
{/*ALCODESTART::1734716016619*/
v_batteryMoneyMade_euro = 0;
+v_currentLoadLowPassed_kW = 0;
/*ALCODEEND*/}
-double f_batteryManagementBalanceNoGCCapacity_NBH(double batterySOC)
+double f_batteryManagementBalanceNoGCCapacity_NBH()
{/*ALCODESTART::1736869275213*/
//traceln("Battery storage capacity: " + ((J_EAStorageElectric)p_batteryAsset.j_ea).getStorageCapacity_kWh());
if (p_batteryAsset.getStorageCapacity_kWh() != 0){
@@ -680,7 +551,7 @@ else if(((J_EAConversionHeatPump)j_ea).getAmbientTempType() == OL_AmbientTempTyp
double FeedforwardGain_kWpKw = 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 * currentLoadDeviation_kW + (SOC_setp_fr - batterySOC) * FeedbackGain_kWpSOC;
+ chargeSetpoint_kW = -FeedforwardGain_kWpKw * currentLoadDeviation_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("v_powerFraction_fr" + p_batteryAsset.v_powerFraction_fr);
diff --git a/_alp/Agents/GCNeighborhood/Code/Functions.xml b/_alp/Agents/GCNeighborhood/Code/Functions.xml
index c2a3b1ea..ce787a35 100644
--- a/_alp/Agents/GCNeighborhood/Code/Functions.xml
+++ b/_alp/Agents/GCNeighborhood/Code/Functions.xml
@@ -129,46 +129,6 @@
-
- VOID
- double
- 1730897215443
-
- 920
- 280
-
- 10
- 0
-
- false
- false
- true
-
-
-
-
-
-
-
- VOID
- double
- 1730897215446
-
- 920
- 300
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
-
-
VOID
double
@@ -259,10 +219,6 @@
false
false
true
-
-
-
-
diff --git a/_alp/Agents/GCNeighborhood/Variables.xml b/_alp/Agents/GCNeighborhood/Variables.xml
index f6af3944..7ef3c6a3 100644
--- a/_alp/Agents/GCNeighborhood/Variables.xml
+++ b/_alp/Agents/GCNeighborhood/Variables.xml
@@ -494,6 +494,25 @@
+
+ 1752589060012
+
+ 1270
+ 450
+
+ 10
+ 0
+
+ false
+ true
+ true
+
+
+
+
1722588367044
diff --git a/_alp/Agents/GCPublicCharger/AOC.GCPublicCharger.xml b/_alp/Agents/GCPublicCharger/AOC.GCPublicCharger.xml
index 4c7a973d..e8a6dff0 100644
--- a/_alp/Agents/GCPublicCharger/AOC.GCPublicCharger.xml
+++ b/_alp/Agents/GCPublicCharger/AOC.GCPublicCharger.xml
@@ -3,6 +3,7 @@
1717956409506
+ 1752677823817
zero_engine
GridConnection
@@ -41,9 +42,6 @@
-
-
-
@@ -104,6 +102,9 @@
+
+
+
false
diff --git a/_alp/Agents/GCUtility/AOC.GCUtility.xml b/_alp/Agents/GCUtility/AOC.GCUtility.xml
index e5839dff..2700594e 100644
--- a/_alp/Agents/GCUtility/AOC.GCUtility.xml
+++ b/_alp/Agents/GCUtility/AOC.GCUtility.xml
@@ -3,6 +3,7 @@
1672138285227
+ 1752677823817
zero_engine
GridConnection
@@ -41,9 +42,6 @@
-
-
-
@@ -104,6 +102,9 @@
+
+
+
false
diff --git a/_alp/Agents/GCUtility/Code/Functions.java b/_alp/Agents/GCUtility/Code/Functions.java
index a5adc7b0..696ed1cd 100644
--- a/_alp/Agents/GCUtility/Code/Functions.java
+++ b/_alp/Agents/GCUtility/Code/Functions.java
@@ -1,65 +1,14 @@
double f_operateFlexAssets_overwrite()
{/*ALCODESTART::1698936515692*/
f_manageHeatingAssets();
-/*for ( J_EAStorage e : c_storageAssets ) {
- v_currentPowerHeat_kW += e.heatConsumption_kW - e.heatProduction_kW; //peter 13-3-23: ik snap niet waarom dit hier staat. dit komt in de knoop met andere storage assets (zoals batterij)
-}*/
f_manageCharging();
-if (p_batteryAsset != null){ // TEST CODE
- if (p_batteryAsset.getStorageCapacity_kWh() > 0 && p_batteryAsset.getCapacityElectric_kW() > 0) {
-
- switch (p_batteryOperationMode) {
- case BALANCE:
- f_batteryManagementBalance(p_batteryAsset.getCurrentStateOfCharge());
- break;
- case SELF_CONSUMPTION:
- f_batteryManagementSelfConsumption();
- break;
- case PRICE:
- f_batteryManagementPrice(p_batteryAsset.getCurrentStateOfCharge());
- break;
- case NODAL_PRICING:
- f_batteryManagementNodalPricing(p_batteryAsset.getCurrentStateOfCharge());
- break;
- case PEAK_SHAVING_SIMPLE:
- f_batteryManagementPeakShaving();
- break;
- }
-
- p_batteryAsset.f_updateAllFlows(p_batteryAsset.v_powerFraction_fr);
- v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge();
- //traceln("flows:" + Arrays.toString(arr));
- //v_batteryPowerElectric_kW = arr[4] - arr[0];
- }
-}
-/*for( J_EAVehicle v: c_vehicleAssets) {
- v_currentPowerElectricity_kW += v.electricityConsumption_kW - v.electricityProduction_kW;
-}*/
-
-//v_currentLoadLowPassed_kW += v_lowPassFactorLoad_fr * ( v_currentPowerElectricity_kW - v_currentLoadLowPassed_kW ); //you want to do deterine the lowpassLoad BEFORE the using the battery. As this behavior of the battery should nog be dependent on the load of the battery in the previous timesteps
+f_manageBattery();
if (v_enableFuelCell) {
f_manageFuelCell();
}
-
-/*if( p_batteryAsset != null){
- switch (p_batteryOperationMode){
- case HOUSEHOLD_LOAD:
- f_batteryManagementBalance(v_batterySOC_fr);
- break;
- case PRICE:
- f_batteryManagementPrice_overwrite(v_batterySOC_fr);
- break;
- default:
- break;
- }
- v_batteryPowerElectric_kW = p_batteryAsset.electricityConsumption_kW - p_batteryAsset.electricityProduction_kW;
- v_currentPowerElectricity_kW +=v_batteryPowerElectric_kW;
- v_batterySOC_fr = p_batteryAsset.getCurrentStateOfCharge();
-}*/
-
/*ALCODEEND*/}
double f_manageFuelCell()
diff --git a/_alp/Agents/GIS_Building/AOC.GIS_Building.xml b/_alp/Agents/GIS_Building/AOC.GIS_Building.xml
index 6cdb4471..c4d56b06 100644
--- a/_alp/Agents/GIS_Building/AOC.GIS_Building.xml
+++ b/_alp/Agents/GIS_Building/AOC.GIS_Building.xml
@@ -3,6 +3,7 @@
1676382560905
+ 1752681631114
zero_engine
GIS_Object
diff --git a/_alp/Agents/GIS_Object/AOC.GIS_Object.xml b/_alp/Agents/GIS_Object/AOC.GIS_Object.xml
index 8094eee7..42e32d4e 100644
--- a/_alp/Agents/GIS_Object/AOC.GIS_Object.xml
+++ b/_alp/Agents/GIS_Object/AOC.GIS_Object.xml
@@ -3,6 +3,7 @@
1667726338857
+ 1752681631114
false
1667726338855
diff --git a/_alp/Agents/GIS_Parcel/AOC.GIS_Parcel.xml b/_alp/Agents/GIS_Parcel/AOC.GIS_Parcel.xml
index 056172c3..8cc26408 100644
--- a/_alp/Agents/GIS_Parcel/AOC.GIS_Parcel.xml
+++ b/_alp/Agents/GIS_Parcel/AOC.GIS_Parcel.xml
@@ -3,6 +3,7 @@
1660572036696
+ 1752681631114
zero_engine
GIS_Object
diff --git a/_alp/Agents/GovernmentLayer/AOC.GovernmentLayer.xml b/_alp/Agents/GovernmentLayer/AOC.GovernmentLayer.xml
index 5ec4ff74..0aa4350d 100644
--- a/_alp/Agents/GovernmentLayer/AOC.GovernmentLayer.xml
+++ b/_alp/Agents/GovernmentLayer/AOC.GovernmentLayer.xml
@@ -2,6 +2,7 @@
1660731364525
+ 1752677829820
zero_engine
Actor
diff --git a/_alp/Agents/GridConnection/AOC.GridConnection.xml b/_alp/Agents/GridConnection/AOC.GridConnection.xml
index 4a7f4a2d..195ea4e3 100644
--- a/_alp/Agents/GridConnection/AOC.GridConnection.xml
+++ b/_alp/Agents/GridConnection/AOC.GridConnection.xml
@@ -3,6 +3,7 @@
1658499438203
+ 1752677823817
0 ) { // Look at weather forecast to charge/discharge battery
- SOC_setp_fr = 0.9 - 0.8 * energyModel.v_WindYieldForecast_fr;
- //traceln("Forecast-based SOC setpoint: " + SOC_setp_fr + " %");
- }
- //traceln("SOC setpoint at " + energyModel.t_hourOfDay + " h is " + SOC_setp_fr*100 + "%");
- double FeedbackGain_kWpSOC = 1.5 * p_batteryAsset.getCapacityElectric_kW(); // How strongly to aim for SOC setpoint
- double FeedforwardGain_kWpKw = 0.8; // 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 * (electricitySurplus_kW + chargeOffset_kW) + (SOC_setp_fr - batterySOC) * 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");
-}
-/*ALCODEEND*/}
-
-double f_batteryManagementPrice(double currentBatteryStateOfCharge)
-{/*ALCODESTART::1669022552780*/
-if (p_batteryAsset.getStorageCapacity_kWh() != 0){
- //double willingnessToPayDefault_eurpkWh = 0.3;
- double chargeDischarge_offset_eurpkWh = 0.0;
- double WTPfeedbackGain_eurpSOC = 0.5; // When SOC-error is 100%, adjust WTP price by 1 eurpkWh
- double priceGain_kWhpeur = 2; // How strongly to ramp up power with price-delta's
- //double congestionTariffCoop_eurpkWh = -(((ConnectionOwner)p_ownerActor).p_CoopParent.v_electricitySurplus_kW + v_previousPowerElectricity_kW)/1200*0.1;
-
- double chargeSetpoint_kW = 0;
-
- if( p_owner != null) {
- //traceln("Initial Mappings are: " + ((ConnectionOwner)p_ownerActor).v_currentPriceBands);
- double currentElectricityPriceCharge_eurpkWh = p_owner.f_getElectricityPrice(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)+100.0); // query price at 100kW charging
- double currentElectricityPriceDischarge_eurpkWh = p_owner.f_getElectricityPrice(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)-100.0); // query price at -100kW charging
- //double lowPassFraction = min(1,1*1.2*energyModel.p_timeStep_h); // smaller value results in more filtering
- v_electricityPriceLowPassed_eurpkWh += v_lowPassFactor_fr * ( currentElectricityPriceCharge_eurpkWh - v_electricityPriceLowPassed_eurpkWh );
-
- //double currentPricePowerBandPos_kW = ownerActor.v_priceBandsDelivery.ceilingKey(100.0); // Up to what power does this price hold?
- //double currentPricePowerBandNeg_kW = ownerActor.v_priceBandsDelivery.floorKey(100.0); // Down to what power does this price hold?
-
- double SOC_setp_fr = 0.5;
- //traceln("Current price is " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, between " + currentPricePowerBandNeg_kW + " kW and " + currentPricePowerBandPos_kW + " kW");
- if (!c_vehicleAssets.isEmpty()) {
- SOC_setp_fr = 0.5 + 0.25 * Math.sin(2*Math.PI*(energyModel.t_h-12)/24); // Sinusoidal setpoint: aim for low SOC at 6:00h, high SOC at 18:00h.
- } else if (energyModel.v_liveAssetsMetaData.totalInstalledWindPower_kW > 0 ) {
- SOC_setp_fr = 0.9 - 0.8 * energyModel.v_WindYieldForecast_fr;
- //traceln("Forecast-based SOC setpoint: " + SOC_setp_fr + " %");
- }
- double SOC_deficit_fr = SOC_setp_fr - currentBatteryStateOfCharge; // How far away from desired SOC? SOC too LOW is a POSITIVE deficit
-
- // Define WTP price for charging and discharging!
- double WTP_charge_eurpkWh = v_electricityPriceLowPassed_eurpkWh - chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
- double WTP_discharge_eurpkWh = v_electricityPriceLowPassed_eurpkWh + chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
-
- //traceln("WTP charge is " + WTP_charge_eurpkWh + " eurpkWh, discharge is " + WTP_discharge_eurpkWh + " eurpkWh");
- // Choose charging power based on prices and desired SOC level
- if ( WTP_charge_eurpkWh > currentElectricityPriceCharge_eurpkWh ) { // if willingness to pay higher than current electricity price
- //chargeSetpoint_kW = min(p_batteryAsset.getElectricCapacity_kW()*(WTP_charge_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain, currentPricePowerBandPos_kW) ;
- chargeSetpoint_kW = p_batteryAsset.getCapacityElectric_kW()*(WTP_charge_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain_kWhpeur;
- //traceln("WTP charge " + WTP_charge_eurpkWh + " eurpkWh is high than electricity price " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, so charge!") ;
- } else if (WTP_discharge_eurpkWh < currentElectricityPriceDischarge_eurpkWh) {
- //chargeSetpoint_kW = -min(p_batteryAsset.getElectricCapacity_kW()*(currentElectricityPriceDischarge_eurpkWh - WTP_discharge_eurpkWh)*priceGain, currentPricePowerBandPos_kW);
- chargeSetpoint_kW = -p_batteryAsset.getCapacityElectric_kW()*(currentElectricityPriceDischarge_eurpkWh - WTP_discharge_eurpkWh)*priceGain_kWhpeur;
- //traceln("WTP discharge " + WTP_discharge_eurpkWh + " eurpkWh is lower than electricity price " + currentElectricityPriceCharge_eurpkWh + " eurpkWh, so discharge!") ;
- }
-
- // limit charging power to available connection capacity
- boolean b_stayWithinConnectionLimits = true;
- if( b_stayWithinConnectionLimits ) {
- double electricitySurplus_kW = - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY);
-
- double availableChargePower_kW = electricitySurplus_kW + v_liveConnectionMetaData.contractedDeliveryCapacity_kW; // Max battery charging power within grid capacity
- double availableDischargePower_kW = electricitySurplus_kW - v_liveConnectionMetaData.contractedFeedinCapacity_kW; // Max discharging power within grid capacity
- 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
- }
-}
-
-/*ALCODEEND*/}
-
double f_manageHeatingAssets()
{/*ALCODESTART::1669025846794*/
// TODO: This only works for fixed heat demands; also need to implement heating of a building modeled as a ThermalStorageAsset! [GH 21/11/2022]
@@ -359,7 +261,7 @@ else if (p_primaryHeatingAsset== null && p_secondaryHeatingAsset != null && v_ha
for ( int i = 0; i < copiedVehicleList.size(); i++ ) {
J_EAEV ev = copiedVehicleList.get(i);
if (ev.vehicleScaling != 0) {
- if( !ev.getAvailability() || ev.getCurrentStateOfCharge() == 1 ) {
+ if( !ev.getAvailability() || ev.getCurrentStateOfCharge_fr() == 1 ) {
ev.f_updateAllFlows( 0.0 );
c_vehiclesAvailableForCharging.remove( i - countDeletedItems );
countDeletedItems ++;
@@ -379,17 +281,17 @@ else if (p_primaryHeatingAsset== null && p_secondaryHeatingAsset != null && v_ha
for ( int i = 0; i < copiedVehicleList.size(); i++ ){
J_EAEV ev = copiedVehicleList.get(i);
if (ev.vehicleScaling != 0) {
- if(!ev.getAvailability() || ev.getCurrentStateOfCharge() == 1) {
+ if(!ev.getAvailability() || ev.getCurrentStateOfCharge_fr() == 1) {
ev.f_updateAllFlows( 0.0 );
c_vehiclesAvailableForCharging.remove( i - countDeletedItems );
countDeletedItems ++;
}
else {
- double chargeNeedForNextTrip_kWh = max(0, ev.getEnergyNeedForNextTrip_kWh() - ev.getStorageCapacity_kWh()*ev.getCurrentStateOfCharge());
+ double chargeNeedForNextTrip_kWh = max(0, ev.getEnergyNeedForNextTrip_kWh() - ev.getCurrentStateOfCharge_kWh());
double maxChargingPower_kW = ev.getCapacityElectric_kW();
double chargeDeadline_h = floor((ev.tripTracker.v_nextEventStartTime_min / 60 - chargeNeedForNextTrip_kWh / maxChargingPower_kW) / energyModel.p_timeStep_h) * energyModel.p_timeStep_h;
- double emptyKWhInBattery = ev.getStorageCapacity_kWh() * (1 - ev.getCurrentStateOfCharge());
+ double emptyKWhInBattery = ev.getStorageCapacity_kWh() - ev.getCurrentStateOfCharge_kWh();
double timeToNextTrip_h = ev.tripTracker.v_nextEventStartTime_min / 60 - energyModel.t_h;
// At the end of the simulation the triptracker returns back to the start of the year, so we make sure the timeToNextTrip is not negative
timeToNextTrip_h = (timeToNextTrip_h % 8760 + 8760) % 8760;
@@ -425,7 +327,7 @@ else if (p_primaryHeatingAsset== null && p_secondaryHeatingAsset != null && v_ha
for ( int i = 0; i < copiedVehicleList.size(); i++ ){
J_EAEV ev = copiedVehicleList.get(i);
if (ev.vehicleScaling != 0) {
- if( !ev.getAvailability() || ev.getCurrentStateOfCharge() == 1 ) {
+ if( !ev.getAvailability() || ev.getCurrentStateOfCharge_fr() == 1 ) {
ev.f_updateAllFlows( 0.0 );
c_vehiclesAvailableForCharging.remove( i - countDeletedItems );
countDeletedItems ++;
@@ -434,7 +336,7 @@ else if (p_primaryHeatingAsset== null && p_secondaryHeatingAsset != null && v_ha
//traceln("current time: " + energyModel.t_h);
//traceln("ev: " + ev);
//traceln("dist: " + ev.getTripTracker().v_tripDist_km);
- double chargeNeedForNextTrip_kWh = max(0, ev.getEnergyNeedForNextTrip_kWh() - ev.getStorageCapacity_kWh()*ev.getCurrentStateOfCharge());
+ double chargeNeedForNextTrip_kWh = max(0, ev.getEnergyNeedForNextTrip_kWh() - ev.getCurrentStateOfCharge_kWh());
//traceln("chargeNeedForNextTrip_kWh: " + chargeNeedForNextTrip_kWh);
double maxChargingPower_kW = ev.getCapacityElectric_kW();
double chargeDeadline_h = floor((ev.tripTracker.v_nextEventStartTime_min / 60 - chargeNeedForNextTrip_kWh / maxChargingPower_kW) / energyModel.p_timeStep_h) * energyModel.p_timeStep_h;
@@ -487,7 +389,7 @@ else if (p_primaryHeatingAsset== null && p_secondaryHeatingAsset != null && v_ha
countDeletedItems ++;
} else {
//double availableChargingPower_kW = v_allowedCapacity_kW - v_currentPowerElectricity_kW - v_chargingPower_kW;
- double chargeNeedForNextTrip_kWh = max(0, vehicle.energyNeedForNextTrip_kWh - vehicle.getStorageCapacity_kWh()*vehicle.getCurrentStateOfCharge());
+ double chargeNeedForNextTrip_kWh = max(0, vehicle.energyNeedForNextTrip_kWh - vehicle.getCurrentStateOfCharge_kWh());
//double timeToNexTrip_min = vehicle.getMobilityTracker().v_nextTripStartTime_min - energyModel.t_h*60;
double maxChargingPower_kW = vehicle.getCapacityElectric_kW();
double timeToNextTrip_min = vehicle.tripTracker.v_nextEventStartTime_min - energyModel.t_h*60;
@@ -504,7 +406,7 @@ else if (p_primaryHeatingAsset== null && p_secondaryHeatingAsset != null && v_ha
if ( energyModel.t_h*60 >= chargeDeadline_min & chargeNeedForNextTrip_kWh > 0) { // Must-charge time at max charging power
//traceln("Urgency charging! May exceed connection capacity!");
chargeSetpoint_kW = maxChargingPower_kW;
- } else if ( vehicle.getCurrentStateOfCharge() < 0.15 ) {
+ } else if ( vehicle.getCurrentStateOfCharge_fr() < 0.15 ) {
chargeSetpoint_kW = min(remainingChargePower_kW, maxChargingPower_kW);
} else {
//double WTPprice_eurpkWh = v_electricityPriceLowPassed_eurpkWh - flexibilityGain_eurph * (chargeDeadline_min - energyModel.t_h*60 - 600);
@@ -531,7 +433,7 @@ else if (p_primaryHeatingAsset== null && p_secondaryHeatingAsset != null && v_ha
}
if( this instanceof GCHouse){
- ((GCHouse)this).v_vehicleSOC_fr = vehicle.getCurrentStateOfCharge();
+ ((GCHouse)this).v_vehicleSOC_fr = vehicle.getCurrentStateOfCharge_fr();
}
}
@@ -784,7 +686,7 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){
countDeletedItems ++;
} else {
//double availableChargingPower_kW = v_allowedCapacity_kW - v_currentPowerElectricity_kW - v_chargingPower_kW;
- double chargeNeedForNextTrip_kWh = vehicle.energyNeedForNextTrip_kWh - vehicle.getStorageCapacity_kWh()*vehicle.getCurrentStateOfCharge();
+ double chargeNeedForNextTrip_kWh = vehicle.energyNeedForNextTrip_kWh - vehicle.getCurrentStateOfCharge_kWh();
//double timeToNexTrip_min = vehicle.getMobilityTracker().v_nextTripStartTime_min - energyModel.t_h*60;
double maxChargingPower_kW = vehicle.getCapacityElectric_kW();
double timeToNextTrip_min = vehicle.tripTracker.v_nextEventStartTime_min - energyModel.t_h*60;
@@ -806,7 +708,7 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){
if ( energyModel.t_h*60 >= chargeDeadline_min & chargeNeedForNextTrip_kWh > 0) { // Must-charge time at max charging power
//traceln("Urgency charging! May exceed connection capacity!");
chargeSetpoint_kW = maxChargingPower_kW;
- } else if ( vehicle.getCurrentStateOfCharge() < 0.15 ) {
+ } else if ( vehicle.getCurrentStateOfCharge_fr() < 0.15 ) {
chargeSetpoint_kW = min(remainingChargePower_kW, maxChargingPower_kW);
} else {
//double WTPprice_eurpkWh = v_electricityPriceLowPassed_eurpkWh - flexibilityGain_eurph * (chargeDeadline_min - energyModel.t_h*60 - 600);
@@ -836,7 +738,7 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){
}
if( this instanceof GCHouse){
- ((GCHouse)this).v_vehicleSOC_fr = vehicle.getCurrentStateOfCharge();
+ ((GCHouse)this).v_vehicleSOC_fr = vehicle.getCurrentStateOfCharge_fr();
}
}
@@ -1240,55 +1142,6 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){
v_liveConnectionMetaData.contractedFeedinCapacity_kW += mult * v_nfatoWeekFeedinCapacity_kW[hourOfDay];
}
}
-/*ALCODEEND*/}
-
-double f_batteryManagementNodalPricing(double currentBatteryStateOfCharge_fr)
-{/*ALCODESTART::1720537137235*/
-if (p_batteryAsset.getStorageCapacity_kWh() != 0){
- //double willingnessToPayDefault_eurpkWh = 0.3;
- double WTPfeedbackGain_eurpSOC = 0.2; // When SOC-error is 100%, adjust WTP price by 1 eurpkWh
- double priceGain_kWhpeur = 1.0; // How strongly to ramp up power with price-delta's. Increasing this gain too far leads to instability!
- //double congestionTariffCoop_eurpkWh = -(((ConnectionOwner)p_ownerActor).p_CoopParent.v_electricitySurplus_kW + v_previousPowerElectricity_kW)/1200*0.1;
-
- double chargeSetpoint_kW = 0;
- double currentElectricityPriceCharge_eurpkWh;
- //double currentElectricityPriceDischarge_eurpkWh;
- //currentElectricityPriceCharge_eurpkWh = energyModel.nationalEnergyMarket.f_getNationalElectricityPrice_eurpMWh()/1000 + GN.v_currentTotalNodalPrice_eurpkWh;
- currentElectricityPriceCharge_eurpkWh = p_parentNodeElectric.v_currentTotalNodalPrice_eurpkWh;
-
- v_electricityPriceLowPassed_eurpkWh += v_lowPassFactor_fr * ( currentElectricityPriceCharge_eurpkWh - v_electricityPriceLowPassed_eurpkWh );
-
-
- double SOC_setp_fr = 0.9 + (p_parentNodeElectric.v_totalInstalledPVPower_kW/50_000+p_parentNodeElectric.v_totalInstalledWindPower_kW/20_000)*(0.2 - 3*p_parentNodeElectric.v_electricityYieldForecast_fr);
- //double SOC_setp_fr = 0.9 - 2*energyModel.v_WindYieldForecast_fr;
- //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*(energyModel.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 WTP_eurpkWh = v_electricityPriceLowPassed_eurpkWh + 1.0*(energyModel.v_epexForecast_eurpkWh - v_electricityPriceLowPassed_eurpkWh) + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
- double WTP_eurpkWh = v_electricityPriceLowPassed_eurpkWh + 0.0*(energyModel.v_epexForecast_eurpkWh - v_electricityPriceLowPassed_eurpkWh) + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
- chargeSetpoint_kW = p_batteryAsset.getCapacityElectric_kW()*(WTP_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain_kWhpeur ;
-
- //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.getElectricCapacity_kW())); // Convert to powerFraction and limit power
- boolean b_stayWithinConnectionLimits = true;
- if( b_stayWithinConnectionLimits ) {
- double maxBatteryPower_kW = v_liveConnectionMetaData.contractedDeliveryCapacity_kW - (fm_currentConsumptionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - fm_currentProductionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)); // Max battery charging power within grid capacity
- double minBatteryPower_kW = - (v_liveConnectionMetaData.contractedFeedinCapacity_kW + (fm_currentConsumptionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - fm_currentProductionFlows_kW.get(OL_EnergyCarriers.ELECTRICITY))); // Max discharging power within grid capacity (this number is usually negative!)
- chargeSetpoint_kW = min(max(chargeSetpoint_kW, minBatteryPower_kW),maxBatteryPower_kW); // Don't allow too much (dis)charging!
- /*if (minBatteryPower_kW>0) {
- traceln("Battery must charge to prevent curtailment! minBatteryPower_kW: %s, chargeSetpoint_kW: %s, battery SOC: %s", minBatteryPower_kW, chargeSetpoint_kW, currentBatteryStateOfCharge_fr);
- }*/
- }
-
- p_batteryAsset.v_powerFraction_fr = max(-1,min(1, chargeSetpoint_kW / p_batteryAsset.getCapacityElectric_kW())); // Convert to powerFraction and limit power
-}
-
-//traceln("Hello!");
-
-
-
/*ALCODEEND*/}
double f_removeFlows(J_FlowsMap flowsMap,double energyUse_kW,J_EA caller)
@@ -1355,7 +1208,7 @@ else if (flowsMap.get(EC) > 0){
for (J_EA j_ea : c_fixedConsumptionElectricAssets) {
v_fixedConsumptionElectric_kW += j_ea.getLastFlows().get(OL_EnergyCarriers.ELECTRICITY);
}
-v_liveData.data_baseloadElectricityDemand_kW.add(currentTime_h, v_fixedConsumptionElectric_kW);
+v_liveData.data_baseloadElectricityDemand_kW.add(currentTime_h, roundToDecimal(v_fixedConsumptionElectric_kW, 3));
//Cooking
@@ -1402,7 +1255,7 @@ else if (flowsMap.get(EC) > 0){
for (J_EA j_ea : c_batteryAssets) {
if (((J_EAStorageElectric)j_ea).getCapacityElectric_kW() != 0 && ((J_EAStorageElectric)j_ea).getStorageCapacity_kWh() != 0) {
v_batteryPowerElectric_kW += j_ea.getLastFlows().get(OL_EnergyCarriers.ELECTRICITY);
- v_batteryStoredEnergy_kWh += ((J_EAStorageElectric)j_ea).getStorageCapacity_kWh()*((J_EAStorageElectric)j_ea).getCurrentStateOfCharge();
+ v_batteryStoredEnergy_kWh += ((J_EAStorageElectric)j_ea).getStorageCapacity_kWh()*((J_EAStorageElectric)j_ea).getCurrentStateOfCharge_fr();
}
}
v_liveData.data_batteryCharging_kW.add(currentTime_h, roundToDecimal(max(0, v_batteryPowerElectric_kW), 3));
@@ -1546,7 +1399,7 @@ else if (flowsMap.get(EC) > 0){
for (J_EA j_ea : c_batteryAssets) {
if (((J_EAStorageElectric)j_ea).getCapacityElectric_kW() != 0 && ((J_EAStorageElectric)j_ea).getStorageCapacity_kWh() != 0) {
v_batteryPowerElectric_kW += j_ea.getLastFlows().get(OL_EnergyCarriers.ELECTRICITY);
- v_batteryStoredEnergy_kWh += ((J_EAStorageElectric)j_ea).getStorageCapacity_kWh()*((J_EAStorageElectric)j_ea).getCurrentStateOfCharge();
+ v_batteryStoredEnergy_kWh += ((J_EAStorageElectric)j_ea).getStorageCapacity_kWh()*((J_EAStorageElectric)j_ea).getCurrentStateOfCharge_fr();
}
}
@@ -1807,22 +1660,13 @@ else if (flowsMap.get(EC) > 0){
double f_getChargeDeadline(J_EAEV ev)
{/*ALCODESTART::1725455130676*/
-double chargeNeedForNextTrip_kWh = max(0, ev.getEnergyNeedForNextTrip_kWh() - ev.getStorageCapacity_kWh()*ev.getCurrentStateOfCharge());
+double chargeNeedForNextTrip_kWh = max(0, ev.getEnergyNeedForNextTrip_kWh() - ev.getCurrentStateOfCharge_kWh());
double maxChargingPower_kW = ev.getCapacityElectric_kW();
return floor((ev.tripTracker.v_nextEventStartTime_min / 60 - chargeNeedForNextTrip_kWh / maxChargingPower_kW) / energyModel.p_timeStep_h) * energyModel.p_timeStep_h;
/*ALCODEEND*/}
-double f_batteryManagementSelfConsumption()
-{/*ALCODESTART::1725629047745*/
-if (p_batteryAsset.getStorageCapacity_kWh() != 0){
- double chargeSetpoint_kW = - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY);
- // limit charging power to battery max power.
- p_batteryAsset.v_powerFraction_fr = max(-1,min(1, chargeSetpoint_kW / p_batteryAsset.getCapacityElectric_kW()));
-}
-/*ALCODEEND*/}
-
double f_initializeDataSets()
{/*ALCODESTART::1730728785333*/
v_liveData.dsm_liveDemand_kW.createEmptyDataSets(v_activeEnergyCarriers, (int)(168 / energyModel.p_timeStep_h));
@@ -1859,84 +1703,6 @@ else if (flowsMap.get(EC) > 0){
}
/*ALCODEEND*/}
-double f_batteryManagementPeakShaving()
-{/*ALCODESTART::1750763679197*/
-if (p_batteryAsset.getStorageCapacity_kWh() != 0){
- int index = roundToInt((energyModel.t_h % 24)/energyModel.p_timeStep_h);
- if(index == 0){
- f_peakShavingForecast_simple();
- }
- p_batteryAsset.v_powerFraction_fr = max(-1,min(1, v_batteryChargingForecast_kW[index] / p_batteryAsset.getCapacityElectric_kW()));
-}
-/*ALCODEEND*/}
-
-double f_peakShavingForecast_simple()
-{/*ALCODESTART::1750763679201*/
-double amountOfHoursInADay = 24;
-double[] nettoBalance_kW = new double[96];
-
-//Get elec consumption profile
-J_EAProfile elecConsumptionProfile = findFirst(c_profileAssets, profile -> profile.profileType == OL_ProfileAssetType.ELECTRICITYBASELOAD);
-
-J_EAConsumption elecConsumptionConsumptionAsset = findFirst(c_consumptionAssets, cons -> cons.energyAssetType == OL_EnergyAssetType.ELECTRICITY_DEMAND);
-
-J_EAProduction elecProductionAsset = findFirst(c_productionAssets, prod -> prod.energyAssetType == OL_EnergyAssetType.PHOTOVOLTAIC);
-
-//For simulation that cross the year end
-double hour_of_simulation_year = energyModel.t_h - energyModel.p_runStartTime_h;
-//traceln("hour_of_year: " + hour_of_simulation_year);
-
-int startTimeDayIndex = roundToInt(hour_of_simulation_year/energyModel.p_timeStep_h);
-int endTimeDayIndex = roundToInt((hour_of_simulation_year + 24)/energyModel.p_timeStep_h);
-
-if(elecConsumptionProfile != null){
- nettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecConsumptionProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), 1/energyModel.p_timeStep_h);
-}
-if(elecConsumptionConsumptionAsset != null){
- for(double time = energyModel.t_h; time < energyModel.t_h + 24; time += energyModel.p_timeStep_h){
- nettoBalance_kW[roundToInt((time-energyModel.t_h)/energyModel.p_timeStep_h)] += elecConsumptionConsumptionAsset.profilePointer.getValue(time)*elecConsumptionConsumptionAsset.yearlyDemand_kWh*elecConsumptionConsumptionAsset.getConsumptionScaling_fr();
- }
-}
-
-if(elecProductionAsset != null){
- for(double time = energyModel.t_h; time < energyModel.t_h + 24; time += energyModel.p_timeStep_h){
- nettoBalance_kW[roundToInt((time-energyModel.t_h)/energyModel.p_timeStep_h)] -= elecProductionAsset.profilePointer.getValue(time)*elecProductionAsset.getCapacityElectric_kW();
- }
-}
-
-
-////Fill chargesetpoint Array
-
-//Initialize chargepoint array
-v_batteryChargingForecast_kW = new double[96];
-
-
-//Calculate the total export over the day that can be collected by the battery
-double totalExport_kWh = 0;
-for(int i = 0; i < nettoBalance_kW.length; i++){
- if(nettoBalance_kW[i] < 0){
- totalExport_kWh += min(p_batteryAsset.getCapacityElectric_kW(), -nettoBalance_kW[i])*energyModel.p_timeStep_h;
- }
-}
-
-
-//Flatten the morning net balance while charging
-double totalDailyImport_kWh = 0;
-for(int i = 0; i < nettoBalance_kW.length; i++){
- if(i< amountOfHoursInADay/energyModel.p_timeStep_h){
- totalDailyImport_kWh += max(0,nettoBalance_kW[i]*energyModel.p_timeStep_h);
- }
-}
-double batteryEnergyNeeded_kWh = max(0,(p_batteryAsset.getStorageCapacity_kWh()*(1-p_batteryAsset.getCurrentStateOfCharge()))-totalExport_kWh);
-double averageDailyConsumption_kW = (totalDailyImport_kWh + batteryEnergyNeeded_kWh)/amountOfHoursInADay;
-
-//If 24 hours
-for(int i = 0; i < nettoBalance_kW.length; i++){
- v_batteryChargingForecast_kW[i] += averageDailyConsumption_kW - nettoBalance_kW[i];
-}
-
-/*ALCODEEND*/}
-
double f_fillLiveDataSets1()
{/*ALCODESTART::1751294546436*/
//Current timestep
@@ -2066,3 +1832,15 @@ else if (flowsMap.get(EC) > 0){
/*ALCODEEND*/}
+double f_manageBattery()
+{/*ALCODESTART::1752570332887*/
+if (p_batteryAsset != null) {
+ if (p_batteryAsset.getStorageCapacity_kWh() > 0 && p_batteryAsset.getCapacityElectric_kW() > 0) {
+ if (p_batteryAlgorithm == null) {
+ throw new RuntimeException("Tried to operate battery without algorithm in GC: " + p_gridConnectionID);
+ }
+ p_batteryAlgorithm.manageBattery();
+ }
+}
+/*ALCODEEND*/}
+
diff --git a/_alp/Agents/GridConnection/Code/Functions.xml b/_alp/Agents/GridConnection/Code/Functions.xml
index 80aa56e7..e0f2bca0 100644
--- a/_alp/Agents/GridConnection/Code/Functions.xml
+++ b/_alp/Agents/GridConnection/Code/Functions.xml
@@ -96,46 +96,6 @@
true
-
- VOID
- double
- 1669022552777
-
- 920
- 280
-
- 10
- 0
-
- false
- false
- true
-
-
-
-
-
-
-
- VOID
- double
- 1669022552780
-
- 920
- 300
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
-
-
VOID
double
@@ -511,30 +471,6 @@
-
- VOID
- double
- 1720537137235
-
-
- 920.6
- 319.4
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
-
-
VOID
double
@@ -636,22 +572,6 @@
-
- VOID
- double
- 1725629047745
-
- 920
- 260
-
- 10
- 0
-
- false
- true
- true
-
-
VOID
double
@@ -687,26 +607,11 @@
VOID
double
- 1750763679197
-
- 920
- 340
-
- 10
- 0
-
- false
- true
- true
-
-
-
- VOID
- double
- 1750763679201
-
- 950
- 360
+ 1751294546436
+
+ true
+ 1610
+ 90
10
0
@@ -719,11 +624,10 @@
VOID
double
- 1751294546436
-
- true
- 1610
- 90
+ 1752570332887
+
+ 930
+ 290
10
0
diff --git a/_alp/Agents/GridConnection/Levels/Level.level.xml b/_alp/Agents/GridConnection/Levels/Level.level.xml
index 8f6c3266..015f3903 100644
--- a/_alp/Agents/GridConnection/Levels/Level.level.xml
+++ b/_alp/Agents/GridConnection/Levels/Level.level.xml
@@ -509,16 +509,6 @@
AUTO
true
LINEAR
-
- Consumption assets demand [kW]
- 1668439095463
- my_dataset
- -10496
- v_fixedConsumptionElectric_kW
- true
- NONE
- 1.0
-
Production assets output [kW]
1668439095464
@@ -589,16 +579,6 @@
NONE
1.0
-
- Current load low passed
- 1658477089939
- my_dataset8
- -16728065
- v_currentLoadLowPassed_kW
- true
- NONE
- 1.0
-
672
48
false
@@ -831,31 +811,6 @@ energyModel.energyDataViewer.viewArea.navigateTo();
View Data
-
- false
- 1746437702494
-
- 510
- -60
-
- 0
- -10
-
- true
- true
- false
- SHAPE_DRAW_2D3D
-
- false
- -16777216
- true
- v_rapidRunData.getFlexPotential();
-
-
-
- notBenuttingsgraad
-
-
1751294528855
diff --git a/_alp/Agents/GridConnection/Variables.xml b/_alp/Agents/GridConnection/Variables.xml
index b68667f6..17ccf1f3 100644
--- a/_alp/Agents/GridConnection/Variables.xml
+++ b/_alp/Agents/GridConnection/Variables.xml
@@ -207,28 +207,6 @@
-
- 1668695288485
-
- 1270
- 350
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
-
-
-
1669725778092
@@ -366,26 +344,6 @@
-
- 1677585426154
-
- true
- 1270
- 490
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
1678710234324
@@ -408,25 +366,6 @@
-
- 1678710234329
-
- 1270
- 450
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
1695824940090
@@ -1090,28 +1029,6 @@
-
- 1750763679203
-
- 970
- 380
-
- 10
- 0
-
- false
- true
- true
-
-
-
-
-
-
-
1751442438903
@@ -1425,34 +1342,6 @@
-
- 1668693418082
-
- 270
- 140
-
- 10
- 0
-
- false
- true
- true
-
-
- NONE
- false
-
-
-
-
- 1668693418080
- TEXT_BOX
- 0
- 100
- NO_DELIMETER
-
-
-
1668695364192
@@ -1535,7 +1424,7 @@
1684919785784
600
- 470
+ 490
10
0
@@ -1966,6 +1855,31 @@
+
+ 1752752664510
+
+ 620
+ 470
+
+ 10
+ 0
+
+ false
+ true
+ true
+
+
+ NONE
+ false
+
+ 1752752664508
+ TEXT_BOX
+ 0
+ 100
+ NO_DELIMETER
+
+
+
1659962626903
@@ -2403,7 +2317,7 @@
1750258408126
600
- 491
+ 511
10
0
diff --git a/_alp/Agents/GridOperator/AOC.GridOperator.xml b/_alp/Agents/GridOperator/AOC.GridOperator.xml
index dd9fd539..ede5fa77 100644
--- a/_alp/Agents/GridOperator/AOC.GridOperator.xml
+++ b/_alp/Agents/GridOperator/AOC.GridOperator.xml
@@ -2,6 +2,7 @@
1660731380915
+ 1752677829820
zero_engine
Actor
diff --git a/_alp/Agents/NationalEnergyMarket/AOC.NationalEnergyMarket.xml b/_alp/Agents/NationalEnergyMarket/AOC.NationalEnergyMarket.xml
index 5d219eb1..993b3bf6 100644
--- a/_alp/Agents/NationalEnergyMarket/AOC.NationalEnergyMarket.xml
+++ b/_alp/Agents/NationalEnergyMarket/AOC.NationalEnergyMarket.xml
@@ -2,6 +2,7 @@
1660731384415
+ 1752677829820
zero_engine
Actor
diff --git a/_alp/Agents/UI_EnergyAsset/AOC.UI_EnergyAsset.xml b/_alp/Agents/UI_EnergyAsset/AOC.UI_EnergyAsset.xml
index 2d3fcd0a..f509c720 100644
--- a/_alp/Agents/UI_EnergyAsset/AOC.UI_EnergyAsset.xml
+++ b/_alp/Agents/UI_EnergyAsset/AOC.UI_EnergyAsset.xml
@@ -4,6 +4,7 @@
true
+ 1752737189062
made explicit function in main to avoid nested functions for easy profiling
//if( assetCategory == PRODUCTION){
// main.c_productionAssets.add(this);
diff --git a/_alp/Agents/UI_GridNode/AOC.UI_GridNode.xml b/_alp/Agents/UI_GridNode/AOC.UI_GridNode.xml
index 6046bc19..83d49904 100644
--- a/_alp/Agents/UI_GridNode/AOC.UI_GridNode.xml
+++ b/_alp/Agents/UI_GridNode/AOC.UI_GridNode.xml
@@ -3,6 +3,7 @@
1658752913454
true
+ 1752737189062
false
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 9c2e6895..00000000
--- a/_alp/Classes/Class.J_BatteryAlgorithmBas.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * J_BatteryAlgorithmBas
- */
-public class J_BatteryAlgorithmBas implements Serializable {
-
- private GridConnection parentGC;
- /**
- * Default constructor
- */
- public J_BatteryAlgorithmBas(GridConnection parentGC) {
-
- this.parentGC = parentGC;
-
- }
-
-
- public double calculateChargeSetpoint_kW(double SOC){
-
- double batteryChargeSetpoint_kW = 0;
-
- //double currentElectricityPriceEPEX_eurpkWh = energyModel.v_epexForecast_eurpkWh;
-
- if (parentGC.p_batteryAsset.getStorageCapacity_kWh() != 0){
- double currentCoopElectricitySurplus_kW = 0;
- double CoopConnectionCapacity_kW = 0;
- double v_previousPowerBattery_kW = parentGC.v_previousPowerElectricity_kW;// Assumes battery is only asset on gridconnection!! p_batteryAsset.electricityConsumption_kW-p_batteryAsset.electricityProduction_kW;
- if(parentGC.p_owner != null) {
- currentCoopElectricitySurplus_kW = -parentGC.p_parentNodeElectric.v_currentLoad_kW + v_previousPowerBattery_kW;
- CoopConnectionCapacity_kW = 0.9*parentGC.p_parentNodeElectric.p_capacity_kW; // Use only 90% of capacity for robustness against delay
- //}
- } else { // Get gridload directly from node
- currentCoopElectricitySurplus_kW = -parentGC.p_parentNodeElectric.v_currentLoad_kW + v_previousPowerBattery_kW;
- CoopConnectionCapacity_kW = 0.95*parentGC.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 * parentGC.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 (parentGC.energyModel.v_currentSolarPowerNormalized_r > 0.1) {
- if (parentGC.p_parentNodeElectric.v_currentLoad_kW < 0) {
- batteryChargeSetpoint_kW = availableChargePower_kW;
- return batteryChargeSetpoint_kW;
- }
- }
- else {
- double expectedWind_kWh = parentGC.p_parentNodeElectric.v_totalInstalledWindPower_kW * parentGC.energyModel.v_WindYieldForecast_fr * parentGC.energyModel.p_forecastTime_h;
- double expectedSolar_kWh = parentGC.p_parentNodeElectric.v_totalInstalledPVPower_kW * parentGC.energyModel.v_SolarYieldForecast_fr * parentGC.energyModel.p_forecastTime_h;
- double incomingPower_fr = (expectedSolar_kWh + expectedWind_kWh) / parentGC.p_batteryAsset.getStorageCapacity_kWh();
- double SOC_setp_fr = 1 - incomingPower_fr;
-
- chargeSetpoint_kW = FeedbackGain_kWpSOC*(SOC_setp_fr - parentGC.p_batteryAsset.getCurrentStateOfCharge());
- 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;
- }
-
- @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_BatteryManagementOff.java b/_alp/Classes/Class.J_BatteryManagementOff.java
new file mode 100644
index 00000000..3d426bcc
--- /dev/null
+++ b/_alp/Classes/Class.J_BatteryManagementOff.java
@@ -0,0 +1,30 @@
+/**
+ * J_BatteryManagementOff
+ */
+public class J_BatteryManagementOff implements I_BatteryManagement {
+
+ GridConnection gc;
+
+ /**
+ * Default constructor
+ */
+ public J_BatteryManagementOff( GridConnection gc) {
+ this.gc = gc;
+ }
+
+ public void manageBattery() {
+ gc.p_batteryAsset.f_updateAllFlows(0.0);
+ }
+
+ @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_BatteryManagementPeakShaving.java b/_alp/Classes/Class.J_BatteryManagementPeakShaving.java
new file mode 100644
index 00000000..e2d55cf1
--- /dev/null
+++ b/_alp/Classes/Class.J_BatteryManagementPeakShaving.java
@@ -0,0 +1,144 @@
+/**
+ * J_BatteryManagementPeakShaving
+ */
+public class J_BatteryManagementPeakShaving implements I_BatteryManagement {
+
+ private GridConnection gc;
+ private Agent target = gc;
+ private OL_ResultScope targetType = OL_ResultScope.GRIDCONNECTION;
+
+ // Parameters used:
+ private double SOC_setpoint_fr = 0.5; // If there are no other influences such as vehicles or production the battery will aim for this SOC_fr
+ private double feedbackGain_fr = 1.5; // This parameter determines how strongly to aim for the SOC setpoint
+
+ /**
+ * Default constructor
+ */
+ public J_BatteryManagementPeakShaving( GridConnection gc ) {
+ this.gc = gc;
+ if (gc instanceof GCGridBattery) {
+ target = null;
+ this.targetType = null;
+ }
+ }
+
+ 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;
+ if (gc instanceof GCGridBattery) {
+ target = null;
+ this.targetType = null;
+ }
+ }
+
+ /**
+ * 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 void manageBattery() {
+ if (this.target == null) {
+ 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;
+
+ // Try to stay within the target connection capacity
+ double v_allowedDeliveryCapacity_kW = getDeliveryCapacity_kW();
+ double v_allowedFeedinCapacity_kW = getFeedinCapacity_kW();
+ double balanceElectricity_kW = getBalanceElectricity_kW();
+ double availableChargePower_kW = v_allowedDeliveryCapacity_kW - balanceElectricity_kW; // Max battery charging power within safety margins
+ 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!
+
+ gc.p_batteryAsset.f_updateAllFlows( chargeSetpoint_kW / gc.p_batteryAsset.getCapacityElectric_kW() );
+ }
+
+ public void setTarget( Agent agent ) {
+ if ( agent == null) {
+ target = null;
+ this.targetType = null;
+ }
+ else if (agent == this.gc) {
+ target = agent;
+ this.targetType = OL_ResultScope.GRIDCONNECTION;
+ }
+ else if (agent instanceof GridNode) {
+ target = agent;
+ this.targetType = OL_ResultScope.GRIDNODE;
+ }
+ else if (agent instanceof EnergyCoop) {
+ target = agent;
+ this.targetType = OL_ResultScope.ENERGYCOOP;
+ }
+ else {
+ throw new RuntimeException("Not able to set " + agent + " as a target for J_BatteryPeakShaving");
+ }
+ }
+
+ public Agent getTarget() {
+ return this.target;
+ }
+
+ public void setTargetType( OL_ResultScope targetType ) {
+ this.targetType = targetType;
+ }
+
+ public OL_ResultScope getTargetType() {
+ return this.targetType;
+ }
+
+ // TODO: Make an interface with at least these 3 functions and make the agents implement it.
+ private double getDeliveryCapacity_kW() {
+ 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() {
+ 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() {
+ switch (targetType) {
+ case GRIDCONNECTION:
+ return gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY);
+ case GRIDNODE:
+ return ((GridNode)target).v_currentLoad_kW - gc.p_batteryAsset.getLastFlows().get(OL_EnergyCarriers.ELECTRICITY);
+ case ENERGYCOOP:
+ return ((EnergyCoop)target).fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - gc.p_batteryAsset.getLastFlows().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);
+ }
+ }
+
+ @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_BatteryManagementPeakShavingForecast.java b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java
new file mode 100644
index 00000000..2f170080
--- /dev/null
+++ b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java
@@ -0,0 +1,103 @@
+import zeroPackage.ZeroMath;
+/**
+ * J_BatteryManagementPeakShavingForecast
+ */
+public class J_BatteryManagementPeakShavingForecast implements I_BatteryManagement {
+
+ private double[] batteryChargingForecast_kW = new double[96];
+ private GridConnection gc;
+ /**
+ * Default constructor
+ */
+ public J_BatteryManagementPeakShavingForecast( GridConnection gc ) {
+ this.gc = gc;
+ }
+
+ /**
+ *
+ */
+ public void manageBattery() {
+ int index = roundToInt((gc.energyModel.t_h % 24)/gc.energyModel.p_timeStep_h);
+ if(index == 0){
+ this.f_peakShavingForecast();
+ }
+ gc.p_batteryAsset.f_updateAllFlows( this.batteryChargingForecast_kW[index] / gc.p_batteryAsset.getCapacityElectric_kW() );
+ }
+
+ private void f_peakShavingForecast() {
+ double amountOfHoursInADay = 24;
+ double[] nettoBalance_kW = new double[96];
+
+ //Get elec consumption profile
+ J_EAProfile elecConsumptionProfile = findFirst(gc.c_profileAssets, profile -> profile.profileType == OL_ProfileAssetType.ELECTRICITYBASELOAD);
+
+ J_EAConsumption elecConsumptionConsumptionAsset = findFirst(gc.c_consumptionAssets, cons -> cons.energyAssetType == OL_EnergyAssetType.ELECTRICITY_DEMAND);
+
+ J_EAProduction elecProductionAsset = findFirst(gc.c_productionAssets, prod -> prod.energyAssetType == OL_EnergyAssetType.PHOTOVOLTAIC);
+
+ //For simulation that cross the year end
+ double hour_of_simulation_year = gc.energyModel.t_h - gc.energyModel.p_runStartTime_h;
+ //traceln("hour_of_year: " + hour_of_simulation_year);
+
+ int startTimeDayIndex = roundToInt(hour_of_simulation_year/gc.energyModel.p_timeStep_h);
+ int endTimeDayIndex = roundToInt((hour_of_simulation_year + 24)/gc.energyModel.p_timeStep_h);
+
+ if(elecConsumptionProfile != null){
+ nettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecConsumptionProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), 1/gc.energyModel.p_timeStep_h);
+ }
+ if(elecConsumptionConsumptionAsset != null){
+ for(double time = gc.energyModel.t_h; time < gc.energyModel.t_h + 24; time += gc.energyModel.p_timeStep_h){
+ nettoBalance_kW[roundToInt((time-gc.energyModel.t_h)/gc.energyModel.p_timeStep_h)] += elecConsumptionConsumptionAsset.profilePointer.getValue(time)*elecConsumptionConsumptionAsset.yearlyDemand_kWh*elecConsumptionConsumptionAsset.getConsumptionScaling_fr();
+ }
+ }
+
+ if(elecProductionAsset != null){
+ for(double time = gc.energyModel.t_h; time < gc.energyModel.t_h + 24; time += gc.energyModel.p_timeStep_h){
+ nettoBalance_kW[roundToInt((time-gc.energyModel.t_h)/gc.energyModel.p_timeStep_h)] -= elecProductionAsset.profilePointer.getValue(time)*elecProductionAsset.getCapacityElectric_kW();
+ }
+ }
+
+
+ ////Fill chargesetpoint Array
+
+ //Initialize chargepoint array
+ this.batteryChargingForecast_kW = new double[96];
+
+
+ //Calculate the total export over the day that can be collected by the battery
+ double totalExport_kWh = 0;
+ for(int i = 0; i < nettoBalance_kW.length; i++){
+ if(nettoBalance_kW[i] < 0){
+ totalExport_kWh += min(gc.p_batteryAsset.getCapacityElectric_kW(), -nettoBalance_kW[i])*gc.energyModel.p_timeStep_h;
+ }
+ }
+
+
+ //Flatten the morning net balance while charging
+ double totalDailyImport_kWh = 0;
+ for(int i = 0; i < nettoBalance_kW.length; i++){
+ if(i< amountOfHoursInADay/gc.energyModel.p_timeStep_h){
+ totalDailyImport_kWh += max(0,nettoBalance_kW[i]*gc.energyModel.p_timeStep_h);
+ }
+ }
+ double batteryEnergyNeeded_kWh = max(0,(gc.p_batteryAsset.getStorageCapacity_kWh()*(1-gc.p_batteryAsset.getCurrentStateOfCharge_fr()))-totalExport_kWh);
+ double averageDailyConsumption_kW = (totalDailyImport_kWh + batteryEnergyNeeded_kWh)/amountOfHoursInADay;
+
+ //If 24 hours
+ for(int i = 0; i < nettoBalance_kW.length; i++){
+ this.batteryChargingForecast_kW[i] += averageDailyConsumption_kW - nettoBalance_kW[i];
+ }
+ return;
+ }
+ @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_BatteryManagementPrice.java b/_alp/Classes/Class.J_BatteryManagementPrice.java
new file mode 100644
index 00000000..e0b542bd
--- /dev/null
+++ b/_alp/Classes/Class.J_BatteryManagementPrice.java
@@ -0,0 +1,81 @@
+/**
+ * J_BatteryManagementPrice
+ */
+public class J_BatteryManagementPrice implements I_BatteryManagement {
+
+ private GridConnection gc;
+ // Parameters used:
+ private boolean stayWithinConnectionLimits = true; // When this flag is true the battery stays within the contracted capacity of the GC
+ private double chargeDischarge_offset_eurpkWh = 0.0; // This term determines the minimal price difference before the battery is used
+ private double WTPfeedbackGain_eurpSOC = 0.5; // This term determines the unwillingness to use the battery when it is almost full or empty
+ private double priceGain_kWhpeur = 2.0; // This term determines how strongly to ramp up power with price-delta's
+ private double lowPassFactor_fr = 0.001;
+
+ // Internal State
+ private double electricityPriceLowPassed_eurpkWh;
+
+ /**
+ * Default constructor
+ */
+ public J_BatteryManagementPrice( GridConnection gc ) {
+ this.gc = gc;
+ }
+
+ 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;
+ this.WTPfeedbackGain_eurpSOC = WTPfeedbackGain_eurpSOC;
+ this.priceGain_kWhpeur = priceGain_kWhpeur;
+ this.lowPassFactor_fr = gc.energyModel.p_timeStep_h / priceTimescale_h;
+ }
+
+ /**
+ * 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 void manageBattery() {
+ // Get the national EPEX price
+ double currentElectricityPriceCharge_eurpkWh = gc.energyModel.nationalEnergyMarket.f_getNationalElectricityPrice_eurpMWh()/1000;
+
+ // Base the WTP on a moving average price and the SOC
+ electricityPriceLowPassed_eurpkWh += lowPassFactor_fr * ( currentElectricityPriceCharge_eurpkWh - electricityPriceLowPassed_eurpkWh );
+
+ double SOC_setpoint_fr = 0.5;
+ double SOC_deficit_fr = SOC_setpoint_fr - gc.p_batteryAsset.getCurrentStateOfCharge_fr(); // How far away from desired SOC? SOC too LOW is a POSITIVE deficit
+
+ // Define WTP price for charging and discharging!
+ double WTP_charge_eurpkWh = electricityPriceLowPassed_eurpkWh - chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
+ double WTP_discharge_eurpkWh = electricityPriceLowPassed_eurpkWh + chargeDischarge_offset_eurpkWh + SOC_deficit_fr * WTPfeedbackGain_eurpSOC;
+
+ // Choose charging power based on prices and desired SOC level
+ double chargeSetpoint_kW = 0;
+ if ( WTP_charge_eurpkWh > currentElectricityPriceCharge_eurpkWh ) {
+ chargeSetpoint_kW = gc.p_batteryAsset.getCapacityElectric_kW()*(WTP_charge_eurpkWh - currentElectricityPriceCharge_eurpkWh)*priceGain_kWhpeur;
+ }
+ else if (WTP_discharge_eurpkWh < currentElectricityPriceCharge_eurpkWh) {
+ chargeSetpoint_kW = -gc.p_batteryAsset.getCapacityElectric_kW()*(currentElectricityPriceCharge_eurpkWh - WTP_discharge_eurpkWh)*priceGain_kWhpeur;
+ }
+
+ // limit charging power to available connection capacity
+ if( stayWithinConnectionLimits ) {
+ double availableChargePower_kW = gc.v_liveConnectionMetaData.contractedDeliveryCapacity_kW - gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); // Max battery charging power within grid capacity
+ double availableDischargePower_kW = gc.v_liveConnectionMetaData.contractedFeedinCapacity_kW + gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); // Max discharging power within grid capacity
+ chargeSetpoint_kW = min(max(chargeSetpoint_kW, -availableDischargePower_kW),availableChargePower_kW); // Don't allow too much (dis)charging!
+ }
+
+ gc.p_batteryAsset.f_updateAllFlows( chargeSetpoint_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_BatteryManagementSelfConsumption.java b/_alp/Classes/Class.J_BatteryManagementSelfConsumption.java
new file mode 100644
index 00000000..8bd32f86
--- /dev/null
+++ b/_alp/Classes/Class.J_BatteryManagementSelfConsumption.java
@@ -0,0 +1,36 @@
+/**
+ * J_BatteryManagementSelfConsumption
+ */
+public class J_BatteryManagementSelfConsumption implements I_BatteryManagement {
+
+ private GridConnection gc;
+
+ /**
+ * Default constructor
+ */
+ public J_BatteryManagementSelfConsumption( GridConnection gc ) {
+ this.gc = gc;
+ }
+
+ /**
+ * One of the simplest battery algorithms.
+ * This algorithm tries to steer the GridConnection load towards 0.
+ * 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 void manageBattery() {
+ gc.p_batteryAsset.f_updateAllFlows( -gc.fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) / 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_EA.java b/_alp/Classes/Class.J_EA.java
index fd64a68f..68529127 100644
--- a/_alp/Classes/Class.J_EA.java
+++ b/_alp/Classes/Class.J_EA.java
@@ -39,9 +39,6 @@ public J_EA() {
*/
public J_EA(Agent parentAgent, double capacityElectric_kW, double capacityHeat_kW, double capacityGas_kW) {
this.parentAgent = parentAgent;
- //this.capacityElectric_kW = capacityElectric_kW;
- //this.capacityHeat_kW = capacityHeat_kW;
- //this.capacityGas_kW = capacityGas_kW;
registerEnergyAsset();
}
@@ -81,16 +78,11 @@ public void removeEnergyAsset() {
}
- //public Pair f_updateAllFlows(double powerFraction_fr) {
public void f_updateAllFlows(double powerFraction_fr) {
double powerFractionBounded_fr = min(1,max(-1, powerFraction_fr));
- //Pair flowsPair = operate(powerFractionBounded_fr);
operate(powerFractionBounded_fr);
- //J_FlowsMap flowsMap = flowsPair.getFirst();
- //return arr;
if (parentAgent instanceof GridConnection) {
- //((GridConnection)parentAgent).f_addFlows(arr, this);
((GridConnection)parentAgent).f_addFlows(flowsMap, this.energyUse_kW, this);
}
/*
@@ -102,12 +94,6 @@ public void f_updateAllFlows(double powerFraction_fr) {
this.lastFlowsMap.cloneMap(this.flowsMap);
this.lastEnergyUse_kW = this.energyUse_kW;
this.clear();
- /*traceln("flowsMap: %s", flowsMap);
- flowsMap.clear();
- traceln("flowsMap after reset: %s", flowsMap);
- traceln("lastflowsMap after flowsmap reset: %s", lastFlowsMap);
- //return arr;*/
- //return this.flowsMap;
}
public void f_updateAllFlows() {
@@ -126,10 +112,6 @@ public void clear() {
public abstract void operate(double ratioOfCapacity);
- public double getCurrentStateOfCharge() {
- return 0;
- }
-
public void storeStatesAndReset() {
// Each energy asset that has some states should overwrite this function!
energyUsedStored_kWh = energyUsed_kWh;
diff --git a/_alp/Classes/Class.J_EABuilding.java b/_alp/Classes/Class.J_EABuilding.java
index 227d6311..b366f702 100644
--- a/_alp/Classes/Class.J_EABuilding.java
+++ b/_alp/Classes/Class.J_EABuilding.java
@@ -5,8 +5,6 @@ public class J_EABuilding extends zero_engine.J_EAStorageHeat implements Seriali
//public OL_EAStorageTypes heatStorageType;
- private double stateOfCharge_r;
-
private double temperature_degC;
private double temperatureStored_degC;
private double initialTemperature_degC;
@@ -180,8 +178,8 @@ protected void updateStateOfCharge( double deltaEnergy_kWh ) {
double tempDelta_degC = deltaEnergy_kWh / (this.heatCapacity_JpK / 3.6E6 );
//traceln("heatCapacity_JpK: %s", heatCapacity_JpK);
this.temperature_degC += tempDelta_degC;
- //this.stateOfCharge_r = ( this.temperature_degC - this.minTemperature_degC) / (this.maxTemperature_degC - this.minTemperature_degC);
- //traceln("SOC: " + stateOfCharge_r);
+ //this.stateOfCharge_fr = ( this.temperature_degC - this.minTemperature_degC) / (this.maxTemperature_degC - this.minTemperature_degC);
+ //traceln("SOC: " + stateOfCharge_fr);
/*if (temperature_degC < setTemperature_degC) {
requiresHeat = true;
@@ -191,11 +189,6 @@ else if ( temperature_degC >= maxTemperature_degC ) {
}*/
}
- @Override
- public double getCurrentStateOfCharge() {
- return this.stateOfCharge_r;
- }
-
@Override
public double getCurrentTemperature() {
return this.temperature_degC;
diff --git a/_alp/Classes/Class.J_EADieselVehicle.java b/_alp/Classes/Class.J_EADieselVehicle.java
index 5e47c81d..b4dd68c7 100644
--- a/_alp/Classes/Class.J_EADieselVehicle.java
+++ b/_alp/Classes/Class.J_EADieselVehicle.java
@@ -57,7 +57,6 @@ public void f_updateAllFlows(double powerFraction_fr) {
public boolean startTrip() {
if (available) {
this.available = false;
- //traceln("storage capacity start of trip: " + storageCapacity_kWh + ", state of charge: " + stateOfCharge_r);
//traceln("Diesel vehicle starting trip!");
return true;
} else {
diff --git a/_alp/Classes/Class.J_EAEV.java b/_alp/Classes/Class.J_EAEV.java
index 57d46709..f8af4f23 100644
--- a/_alp/Classes/Class.J_EAEV.java
+++ b/_alp/Classes/Class.J_EAEV.java
@@ -5,8 +5,8 @@ public class J_EAEV extends J_EAVehicle implements Serializable {
public OL_EnergyCarriers storageMedium = OL_EnergyCarriers.ELECTRICITY;
- private double stateOfCharge_r;
- private double initialStateOfCharge_r;
+ private double stateOfCharge_fr;
+ private double initialstateOfCharge_fr;
private double stateOfChargeStored_r;
protected double capacityElectric_kW;
private double storageCapacity_kWh;
@@ -27,12 +27,12 @@ public J_EAEV() {
/**
* Constructor initializing the fields
*/
- public J_EAEV(Agent parentAgent, double capacityElectricity_kW, double storageCapacity_kWh, double stateOfCharge_r, double timestep_h, double energyConsumption_kWhpkm, double vehicleScaling, OL_EnergyAssetType energyAssetType, J_ActivityTrackerTrips tripTracker) {
+ public J_EAEV(Agent parentAgent, double capacityElectricity_kW, double storageCapacity_kWh, double stateOfCharge_fr, double timestep_h, double energyConsumption_kWhpkm, double vehicleScaling, OL_EnergyAssetType energyAssetType, J_ActivityTrackerTrips tripTracker) {
this.parentAgent = parentAgent;
this.capacityElectric_kW = capacityElectricity_kW; // for EV, this is max charging power.
this.storageCapacity_kWh = storageCapacity_kWh;
- this.initialStateOfCharge_r = stateOfCharge_r;
- this.stateOfCharge_r = initialStateOfCharge_r;
+ this.initialstateOfCharge_fr = stateOfCharge_fr;
+ this.stateOfCharge_fr = initialstateOfCharge_fr;
this.timestep_h = timestep_h;
this.energyConsumption_kWhpkm = energyConsumption_kWhpkm;
this.vehicleScaling = vehicleScaling;
@@ -59,16 +59,16 @@ public void operate(double ratioOfChargeCapacity_r) {
double deltaEnergy_kWh; // to check the request with the energy currently in storage
deltaEnergy_kWh = ( ratioOfChargeCapacity_r * (capacityElectric_kW * vehicleScaling) * timestep_h ) ;
- deltaEnergy_kWh = - min( -deltaEnergy_kWh, (stateOfCharge_r * (storageCapacity_kWh * vehicleScaling)) ); // Prevent negative charge
+ deltaEnergy_kWh = - min( -deltaEnergy_kWh, (stateOfCharge_fr * (storageCapacity_kWh * vehicleScaling)) ); // Prevent negative charge
deltaEnergy_kWh = min(deltaEnergy_kWh, ratioOfChargeCapacity_r * (capacityElectric_kW * vehicleScaling) * timestep_h ); // prevent charging faster than allowed
- deltaEnergy_kWh = min(deltaEnergy_kWh, (1 - stateOfCharge_r) * (storageCapacity_kWh * vehicleScaling) ); // Prevent overcharge
+ deltaEnergy_kWh = min(deltaEnergy_kWh, (1 - stateOfCharge_fr) * (storageCapacity_kWh * vehicleScaling) ); // Prevent overcharge
discharge_kW = -deltaEnergy_kWh / timestep_h;
- //traceln("state of charge: " + stateOfCharge_r * storageCapacity_kWh + ", charged: " + discharge_kW / 4+ " kWh, charging power kW: " + discharge_kW);
+ //traceln("state of charge: " + stateOfCharge_fr * storageCapacity_kWh + ", charged: " + discharge_kW / 4+ " kWh, charging power kW: " + discharge_kW);
double electricityProduction_kW = max(discharge_kW, 0);
double electricityConsumption_kW = max(-discharge_kW, 0);
updateStateOfCharge( discharge_kW );
- //traceln("new state of charge: " + stateOfCharge_r * storageCapacity_kWh);
+ //traceln("new state of charge: " + stateOfCharge_fr * storageCapacity_kWh);
updateChargingHistory( electricityProduction_kW, electricityConsumption_kW );
flowsMap.put(OL_EnergyCarriers.ELECTRICITY, electricityConsumption_kW - electricityProduction_kW);
@@ -77,23 +77,20 @@ public void operate(double ratioOfChargeCapacity_r) {
public void updateStateOfCharge( double power_kW ) {
if(vehicleScaling > 0){
- stateOfCharge_r -= ( power_kW * timestep_h ) / (storageCapacity_kWh * vehicleScaling);
+ stateOfCharge_fr -= ( power_kW * timestep_h ) / (storageCapacity_kWh * vehicleScaling);
}
else {
- stateOfCharge_r = 0;
+ stateOfCharge_fr = 0;
}
}
- @Override
- public double getCurrentStateOfCharge() {
- return stateOfCharge_r;
- }
-
+
+
@Override
public boolean startTrip() {
if (available) {
this.available = false;
- //traceln("storage capacity start of trip: " + storageCapacity_kWh + ", state of charge: " + stateOfCharge_r);
+ //traceln("storage capacity start of trip: " + storageCapacity_kWh + ", state of charge: " + stateOfCharge_fr);
((GridConnection)this.parentAgent).c_vehiclesAvailableForCharging.remove(this);
//Update (charging) flows to zero, becausde vehicle is away.
@@ -118,24 +115,24 @@ public boolean endTrip(double tripDist_km) {
} else {
mileage_km += tripDist_km;
//traceln( "J_EAEV comes back, trip distance: " + tripDist_km + ", energy consumption: " + tripDist_km * energyConsumption_kWhpkm);
- //traceln("EV of type: " + this.energyAssetType + "state of charge: " + stateOfCharge_r);
- stateOfCharge_r -= (tripDist_km * vehicleScaling * energyConsumption_kWhpkm) / (storageCapacity_kWh * vehicleScaling);
- //traceln("storage capacity: " + storageCapacity_kWh + ", state of charge: " + stateOfCharge_r);
+ //traceln("EV of type: " + this.energyAssetType + "state of charge: " + stateOfCharge_fr);
+ stateOfCharge_fr -= (tripDist_km * vehicleScaling * energyConsumption_kWhpkm) / (storageCapacity_kWh * vehicleScaling);
+ //traceln("storage capacity: " + storageCapacity_kWh + ", state of charge: " + stateOfCharge_fr);
energyUsed_kWh += tripDist_km * vehicleScaling * energyConsumption_kWhpkm;
energyUse_kW += tripDist_km * vehicleScaling * energyConsumption_kWhpkm / timestep_h;
//traceln("EV energy use at end of trip: %s kWh", tripDist_km * vehicleScaling * energyConsumption_kWhpkm );
- if (stateOfCharge_r < 0) {
+ if (stateOfCharge_fr < 0) {
//traceln( ownerAsset.date());
//traceln( "Trip distance: " + tripDist_km + ", vehicle scaling: " + vehicleScaling + ", energy cons_kWhpkm: " + energyConsumption_kWhpkm );
- //traceln("EV of type: " + this.energyAssetType + " from GC " + this.parentAgent + " arrived home with negative SOC: " + stateOfCharge_r );
+ //traceln("EV of type: " + this.energyAssetType + " from GC " + this.parentAgent + " arrived home with negative SOC: " + stateOfCharge_fr );
- //energyChargedOutsideModelArea_kWh += -stateOfCharge_r * storageCapacity_kWh;
+ //energyChargedOutsideModelArea_kWh += -stateOfCharge_fr * storageCapacity_kWh;
//traceln("energyChargedOutsideModelArea_kWh: " + energyChargedOutsideModelArea_kWh);
- //stateOfCharge_r = 0;
+ //stateOfCharge_fr = 0;
}
this.available = true;
((GridConnection)this.parentAgent).c_vehiclesAvailableForCharging.add(this);
- //maxSpreadChargingRatio = (1-stateOfCharge_r) * storageCapacity_kWh / (timeToNextTrip_min/60);
+ //maxSpreadChargingRatio = (1-stateOfCharge_fr) * storageCapacity_kWh / (timeToNextTrip_min/60);
return true;
}
}
@@ -146,33 +143,41 @@ public void updateChargingHistory(double electricityProduced_kW, double electric
}
public double getEnergyUsed_kWh() {
- return energyUsed_kWh;
+ return this.energyUsed_kWh;
+ }
+
+ public double getCurrentStateOfCharge_fr() {
+ return this.stateOfCharge_fr;
}
public double getStorageCapacity_kWh() {
- return storageCapacity_kWh * vehicleScaling;
+ return this.storageCapacity_kWh * this.vehicleScaling;
}
-
+
+ public double getCurrentStateOfCharge_kWh() {
+ return this.stateOfCharge_fr * this.getStorageCapacity_kWh();
+ }
+
public double getCapacityElectric_kW() {
- return capacityElectric_kW * vehicleScaling;
+ return this.capacityElectric_kW * this.vehicleScaling;
}
public double getTotalChargeAmount_kWh() {
- return charged_kWh;
+ return this.charged_kWh;
}
public double getTotalDischargeAmount_kWh() {
- return discharged_kWh;
+ return this.discharged_kWh;
}
public double getEnergyNeedForNextTrip_kWh() {
- return energyNeedForNextTrip_kWh * vehicleScaling;
+ return this.energyNeedForNextTrip_kWh * this.vehicleScaling;
}
public boolean getAvailability() {
- return available;
+ return this.available;
}
public double getChargingTimeToFull_MIN() {
- double chargingTime_min = ceil( 60 * ((storageCapacity_kWh * vehicleScaling) - (storageCapacity_kWh * vehicleScaling) * stateOfCharge_r) / (capacityElectric_kW * vehicleScaling) ) ;
+ double chargingTime_min = ceil( 60 * ((storageCapacity_kWh * vehicleScaling) - (storageCapacity_kWh * vehicleScaling) * stateOfCharge_fr) / (capacityElectric_kW * vehicleScaling) ) ;
return chargingTime_min;
}
@@ -184,8 +189,8 @@ public void storeStatesAndReset() {
// Each energy asset that has some states should overwrite this function!
energyUsedStored_kWh = energyUsed_kWh;
energyUsed_kWh = 0.0;
- stateOfChargeStored_r = stateOfCharge_r;
- stateOfCharge_r = initialStateOfCharge_r;
+ stateOfChargeStored_r = stateOfCharge_fr;
+ stateOfCharge_fr = initialstateOfCharge_fr;
availableStored = available;
available = true;
energyChargedOutsideModelAreaStored_kWh = energyChargedOutsideModelArea_kWh;
@@ -200,7 +205,7 @@ public void storeStatesAndReset() {
public void restoreStates() {
// Each energy asset that has some states should overwrite this function!
energyUsed_kWh = energyUsedStored_kWh;
- stateOfCharge_r = stateOfChargeStored_r;
+ stateOfCharge_fr = stateOfChargeStored_r;
available = availableStored;
energyChargedOutsideModelArea_kWh = energyChargedOutsideModelAreaStored_kWh;
charged_kWh = 0;
@@ -210,7 +215,7 @@ public void restoreStates() {
@Override
public String toString() {
return
- "SOC = " + roundToDecimal( stateOfCharge_r, 2 ) + " " +
+ "SOC = " + roundToDecimal( stateOfCharge_fr, 2 ) + " " +
"storageCapacity_kWh = " + storageCapacity_kWh + " " +
"charged_kWh = " + roundToDecimal( charged_kWh, 2 ) + " " +
"mileage = " + roundToDecimal( mileage_km, 2 ) + " ";
diff --git a/_alp/Classes/Class.J_EAHydrogenVehicle.java b/_alp/Classes/Class.J_EAHydrogenVehicle.java
index 70c570be..0239586d 100644
--- a/_alp/Classes/Class.J_EAHydrogenVehicle.java
+++ b/_alp/Classes/Class.J_EAHydrogenVehicle.java
@@ -51,7 +51,6 @@ public void f_updateAllFlows(double powerFraction_fr) {
public boolean startTrip() {
if (available) {
available = false;
- //traceln("storage capacity start of trip: " + storageCapacity_kWh + ", state of charge: " + stateOfCharge_r);
//traceln("Hydrogen vehicle starting trip!");
return true;
} else {
diff --git a/_alp/Classes/Class.J_EAStorage.java b/_alp/Classes/Class.J_EAStorage.java
index f78df1bb..3525c56c 100644
--- a/_alp/Classes/Class.J_EAStorage.java
+++ b/_alp/Classes/Class.J_EAStorage.java
@@ -5,8 +5,8 @@ public abstract class J_EAStorage extends J_EA implements Serializable {
protected OL_EnergyCarriers storageMedium;
protected double storageCapacity_kWh;
- protected double stateOfCharge_r;
- protected double initialStateOfCharge_r;
+ protected double stateOfCharge_fr;
+ protected double initialstateOfCharge_fr;
protected double stateOfChargeStored_r;
//protected double lossFactor_r;
//protected double ambientTemperature_degC;
@@ -21,13 +21,10 @@ public J_EAStorage() {
}
public void calculateLoss() {
- //
}
- //public abstract Pair operate(double ratioOfChargeCapacity_r);
-
protected void updateStateOfCharge( double deltaEnergy_kWh ) {
- stateOfCharge_r += deltaEnergy_kWh / storageCapacity_kWh;
+ stateOfCharge_fr += deltaEnergy_kWh / storageCapacity_kWh;
}
@Override
@@ -35,8 +32,8 @@ public void storeStatesAndReset() {
// Each energy asset that has some states should overwrite this function!
energyUsedStored_kWh = energyUsed_kWh;
energyUsed_kWh = 0.0;
- stateOfChargeStored_r = stateOfCharge_r;
- stateOfCharge_r = initialStateOfCharge_r;
+ stateOfChargeStored_r = stateOfCharge_fr;
+ stateOfCharge_fr = initialstateOfCharge_fr;
charged_kWh = 0;
discharged_kWh = 0;
clear();
@@ -46,19 +43,21 @@ public void storeStatesAndReset() {
public void restoreStates() {
// Each energy asset that has some states should overwrite this function!
energyUsed_kWh = energyUsedStored_kWh;
- stateOfCharge_r = stateOfChargeStored_r;
+ stateOfCharge_fr = stateOfChargeStored_r;
}
- // acces current state of charge
- @Override
- public double getCurrentStateOfCharge() {
- return stateOfCharge_r;
+ public double getCurrentStateOfCharge_fr() {
+ return this.stateOfCharge_fr;
}
public double getStorageCapacity_kWh() {
- return storageCapacity_kWh;
+ return this.storageCapacity_kWh;
}
-
+
+ public double getCurrentStateOfCharge_kWh() {
+ return this.stateOfCharge_fr * this.storageCapacity_kWh;
+ }
+
@Override
public double getCurrentTemperature() {
return 0;
@@ -66,7 +65,6 @@ public double getCurrentTemperature() {
@Override
public void updateAmbientTemperature(double currentAmbientTemperature_degC) {
- //
}
@Override
diff --git a/_alp/Classes/Class.J_EAStorageElectric.java b/_alp/Classes/Class.J_EAStorageElectric.java
index f129f6a0..3c2687a3 100644
--- a/_alp/Classes/Class.J_EAStorageElectric.java
+++ b/_alp/Classes/Class.J_EAStorageElectric.java
@@ -17,12 +17,12 @@ public J_EAStorageElectric() {
/**
* Constructor initializing the fields
*/
- public J_EAStorageElectric(Agent parentAgent, double capacityElectric_kW, double storageCapacity_kWh, double stateOfCharge_r, double timestep_h ) {
+ public J_EAStorageElectric(Agent parentAgent, double capacityElectric_kW, double storageCapacity_kWh, double stateOfCharge_fr, double timestep_h ) {
this.parentAgent = parentAgent;
this.capacityElectric_kW = capacityElectric_kW;
this.storageCapacity_kWh = storageCapacity_kWh;
- this.initialStateOfCharge_r = stateOfCharge_r;
- this.stateOfCharge_r = this.initialStateOfCharge_r;
+ this.initialstateOfCharge_fr = stateOfCharge_fr;
+ this.stateOfCharge_fr = this.initialstateOfCharge_fr;
this.timestep_h = timestep_h;
this.energyAssetType = OL_EnergyAssetType.STORAGE_ELECTRIC;
double eta_r=0.9; // Default cycle efficiency of 90%. Add this as an argument to constructor?
@@ -46,8 +46,8 @@ public void operate(double ratioOfChargeCapacity_r) {
}
// Limit SoC to feasible range (0-1)
- deltaEnergy_kWh = - min( -deltaEnergy_kWh, (stateOfCharge_r * storageCapacity_kWh) ); // Prevent negative charge
- deltaEnergy_kWh = min(deltaEnergy_kWh, (1 - stateOfCharge_r) * storageCapacity_kWh ); // Prevent overcharge
+ deltaEnergy_kWh = - min( -deltaEnergy_kWh, (stateOfCharge_fr * storageCapacity_kWh) ); // Prevent negative charge
+ deltaEnergy_kWh = min(deltaEnergy_kWh, (1 - stateOfCharge_fr) * storageCapacity_kWh ); // Prevent overcharge
double electricityConsumption_kW = 0;
double electricityProduction_kW = 0;
@@ -68,10 +68,8 @@ public void operate(double ratioOfChargeCapacity_r) {
charged_kWh += electricityConsumption_kW * timestep_h; // Not the change-in-SoC, but the energy flowing into the battery before losses.
updateStateOfCharge( deltaEnergy_kWh );
- //traceln("Battery SoC: %s", stateOfCharge_r);
+ //traceln("Battery SoC: %s", stateOfCharge_fr);
flowsMap.put(OL_EnergyCarriers.ELECTRICITY, electricityConsumption_kW-electricityProduction_kW);
-
- //return new Pair(this.flowsMap, this.energyUse_kW);
}
public void setBatteryEfficiency_r(double eta_r) {
@@ -90,7 +88,7 @@ public String toString() {
return
"type = " + this.getClass().toString() + " " +
"parentAgent = " + parentAgent +" " +
- "stateOfCharge_r = " + this.stateOfCharge_r+" "+
+ "stateOfCharge_fr = " + this.stateOfCharge_fr+" "+
"storageCapacity_kWh = " + this.storageCapacity_kWh +" "+
"capacityElectric_kW = " + this.capacityElectric_kW +" "+
"discharged_kWh " + this.discharged_kWh+" "+
@@ -99,21 +97,16 @@ public String toString() {
@Override
protected void updateStateOfCharge( double deltaEnergy_kWh ) {
- stateOfCharge_r += deltaEnergy_kWh / storageCapacity_kWh;
- }
-
- @Override
- public double getCurrentStateOfCharge() {
- return this.stateOfCharge_r;
+ stateOfCharge_fr += deltaEnergy_kWh / storageCapacity_kWh;
}
public double getCapacityAvailable_kW() {
double availableCapacity_kW;
- if ( stateOfCharge_r * storageCapacity_kWh > capacityElectric_kW * timestep_h) {
+ if ( stateOfCharge_fr * storageCapacity_kWh > capacityElectric_kW * timestep_h) {
availableCapacity_kW = capacityElectric_kW;
}
else {
- availableCapacity_kW = stateOfCharge_r * storageCapacity_kWh / timestep_h; // Allow to drain completely
+ availableCapacity_kW = stateOfCharge_fr * storageCapacity_kWh / timestep_h; // Allow to drain completely
}
return availableCapacity_kW;
}
@@ -121,10 +114,6 @@ public double getCapacityAvailable_kW() {
public double getCapacityElectric_kW() {
return this.capacityElectric_kW;
}
-
- public double getStorageCapacity_kWh() {
- return this.storageCapacity_kWh;
- }
public double getTotalChargeAmount_kWh() {
return this.charged_kWh;
@@ -149,9 +138,6 @@ public void setStorageCapacity_kWh(double storageCapacity_kWh) {
public void setCapacityElectric_kW(double capacityElectric_kW) {
this.capacityElectric_kW = capacityElectric_kW;
- //if (capacityElectric_kW == 0) {
- //Arrays.fill(lastFlowsArray,0);
- //}
}
/**
* This number is here for model snapshot storing purpose
diff --git a/_alp/Classes/Class.J_EAStorageGas.java b/_alp/Classes/Class.J_EAStorageGas.java
index dc04edf9..ed72f530 100644
--- a/_alp/Classes/Class.J_EAStorageGas.java
+++ b/_alp/Classes/Class.J_EAStorageGas.java
@@ -6,7 +6,6 @@ public class J_EAStorageGas extends zero_engine.J_EAStorage implements Serializa
private OL_EnergyCarriers energyCarrier = OL_EnergyCarriers.METHANE;
private double lossFactor_r = 0;
protected double capacityGas_kW;
- //public double capacityGas_kW = 0;
/**
* Default constructor
@@ -17,11 +16,11 @@ public J_EAStorageGas() {
/**
* Constructor initializing the fields
*/
- public J_EAStorageGas(Agent parentAgent, double capacityGas_kW, double storageCapacity_kWh, double stateOfCharge_r, double timestep_h ) {
+ public J_EAStorageGas(Agent parentAgent, double capacityGas_kW, double storageCapacity_kWh, double stateOfCharge_fr, double timestep_h ) {
this.parentAgent = parentAgent;
this.capacityGas_kW = capacityGas_kW;
this.storageCapacity_kWh = storageCapacity_kWh;
- this.stateOfCharge_r = stateOfCharge_r;
+ this.stateOfCharge_fr = stateOfCharge_fr;
this.timestep_h = timestep_h;
this.activeProductionEnergyCarriers.add(this.energyCarrier);
this.activeConsumptionEnergyCarriers.add(this.energyCarrier);
@@ -36,14 +35,13 @@ public void calculateLoss() {
}
@Override
- //public Pair operate(double ratioOfChargeCapacity_r) {
public void operate(double ratioOfChargeCapacity_r) {
double deltaEnergy_kWh; // to check the request with the energy currently in storage
double inputPower_kW = ratioOfChargeCapacity_r * capacityGas_kW; // Gas power going into Storage, negative if going out.
deltaEnergy_kWh = inputPower_kW * timestep_h;
- deltaEnergy_kWh = - min( -deltaEnergy_kWh, (stateOfCharge_r * storageCapacity_kWh) ); // Prevent negative charge
- deltaEnergy_kWh = min(deltaEnergy_kWh, (1 - stateOfCharge_r) * storageCapacity_kWh ); // Prevent overcharge
+ deltaEnergy_kWh = - min( -deltaEnergy_kWh, (stateOfCharge_fr * storageCapacity_kWh) ); // Prevent negative charge
+ deltaEnergy_kWh = min(deltaEnergy_kWh, (1 - stateOfCharge_fr) * storageCapacity_kWh ); // Prevent overcharge
inputPower_kW = deltaEnergy_kWh / timestep_h;
@@ -53,12 +51,7 @@ public void operate(double ratioOfChargeCapacity_r) {
charged_kWh += methaneConsumption_kW * timestep_h;
updateStateOfCharge( deltaEnergy_kWh );
- //double[] arr = {electricityProduction_kW, methaneProduction_kW, hydrogenProduction_kW, heatProduction_kW, electricityConsumption_kW, methaneConsumption_kW, hydrogenConsumption_kW, heatConsumption_kW };
- //return arr;
- flowsMap.put(OL_EnergyCarriers.METHANE, methaneConsumption_kW-methaneProduction_kW);
-
- //return this.flowsMap;
-
+ flowsMap.put(OL_EnergyCarriers.METHANE, methaneConsumption_kW-methaneProduction_kW);
}
@Override
@@ -66,7 +59,7 @@ public String toString() {
return
"type = " + this.getClass().toString() + " " +
"parentAgent = " + parentAgent +" " +
- "stateOfCharge_r = " + this.stateOfCharge_r+" "+
+ "stateOfCharge_fr = " + this.stateOfCharge_fr+" "+
"storageCapacity_kWh = " + this.storageCapacity_kWh +" "+
"capacityGas_kW = " + this.capacityGas_kW +" "+
"discharged_kWh " + this.discharged_kWh+" "+
@@ -75,21 +68,16 @@ public String toString() {
@Override
protected void updateStateOfCharge( double deltaEnergy_kWh ) {
- stateOfCharge_r += deltaEnergy_kWh / storageCapacity_kWh;
- }
-
- @Override
- public double getCurrentStateOfCharge() {
- return stateOfCharge_r;
+ stateOfCharge_fr += deltaEnergy_kWh / storageCapacity_kWh;
}
public double getCapacityAvailable_kW() {
double availableCapacity_kW;
- if ( stateOfCharge_r * storageCapacity_kWh > capacityGas_kW * timestep_h) {
+ if ( stateOfCharge_fr * storageCapacity_kWh > capacityGas_kW * timestep_h) {
availableCapacity_kW = capacityGas_kW;
}
else {
- availableCapacity_kW = stateOfCharge_r * storageCapacity_kWh / timestep_h; // Allow to drain completely
+ availableCapacity_kW = stateOfCharge_fr * storageCapacity_kWh / timestep_h; // Allow to drain completely
}
return availableCapacity_kW;
}
diff --git a/_alp/Classes/Class.J_EAStorageHeat.java b/_alp/Classes/Class.J_EAStorageHeat.java
index 4a162b32..c425d84c 100644
--- a/_alp/Classes/Class.J_EAStorageHeat.java
+++ b/_alp/Classes/Class.J_EAStorageHeat.java
@@ -7,7 +7,7 @@ public class J_EAStorageHeat extends zero_engine.J_EAStorage implements Serializ
public OL_EnergyCarriers storageMedium = OL_EnergyCarriers.HEAT;
private double storageCapacity_kWh;
- private double stateOfCharge_r;
+ private double stateOfCharge_fr;
protected double lossFactor_WpK;
protected double capacityHeat_kW;
@@ -58,7 +58,7 @@ public J_EAStorageHeat(Agent parentAgent, OL_EnergyAssetType energyAssetType, do
this.heatCapacity_JpK = heatCapacity_JpK;
this.ambientTempType = ambientTempType;
this.storageCapacity_kWh = ( maxTemperature_degC - minTemperature_degC ) * heatCapacity_JpK / 3.6e+6;
- this.stateOfCharge_r = (( initialTemperature_degC - minTemperature_degC ) / (maxTemperature_degC - minTemperature_degC ) );
+ this.stateOfCharge_fr = (( initialTemperature_degC - minTemperature_degC ) / (maxTemperature_degC - minTemperature_degC ) );
this.activeProductionEnergyCarriers.add(OL_EnergyCarriers.HEAT);
this.activeConsumptionEnergyCarriers.add(OL_EnergyCarriers.HEAT);
registerEnergyAsset();
@@ -151,7 +151,7 @@ public String toString() {
"parentAgent = " + parentAgent +" " +
"capacityElectric_kW = " + this.capacityElectric_kW +" "+
"capacityHeat_kW = " + this.capacityHeat_kW +" "+
- "stateOfCharge_r = " + this.stateOfCharge_r+" "+
+ "stateOfCharge_fr = " + this.stateOfCharge_fr+" "+
"minTemperature_degC = " + this.minTemperature_degC+" "+
"maxTemperature_degC = " + this.maxTemperature_degC+" "+
"setTemperature_degC = " + this.setTemperature_degC+" "+
@@ -165,7 +165,7 @@ public String toString() {
protected void updateStateOfCharge( double deltaEnergy_kWh ) {
double tempDelta_degC = deltaEnergy_kWh / (heatCapacity_JpK / 3.6E6 );
temperature_degC += tempDelta_degC;
- stateOfCharge_r = ( temperature_degC - minTemperature_degC) / (maxTemperature_degC - minTemperature_degC);
+ stateOfCharge_fr = ( temperature_degC - minTemperature_degC) / (maxTemperature_degC - minTemperature_degC);
if (temperature_degC < setTemperature_degC) {
requiresHeat = true;
}
@@ -174,11 +174,6 @@ else if ( temperature_degC >= maxTemperature_degC ) {
}
}
- @Override
- public double getCurrentStateOfCharge() {
- return stateOfCharge_r;
- }
-
@Override
public double getCurrentTemperature() {
return temperature_degC;