From 369cf8da999b0a8d3304278b798fd33be6df2bdb Mon Sep 17 00:00:00 2001 From: Bas Date: Fri, 19 Jun 2026 17:50:02 +0200 Subject: [PATCH 1/3] bugfix LiveDataset size mismatch in Coops --- Zero_engine.alpx | 2 +- _alp/Agents/EnergyCoop/Code/Functions.java | 22 +++++++++++++------ _alp/Agents/GridConnection/Code/Functions.xml | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Zero_engine.alpx b/Zero_engine.alpx index 90810d25..baa6578c 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -1,7 +1,7 @@ 1658477103134 diff --git a/_alp/Agents/EnergyCoop/Code/Functions.java b/_alp/Agents/EnergyCoop/Code/Functions.java index 7807ac8e..6e01200f 100644 --- a/_alp/Agents/EnergyCoop/Code/Functions.java +++ b/_alp/Agents/EnergyCoop/Code/Functions.java @@ -1318,22 +1318,30 @@ HashSet f_getAllChildCustomerGridConnections_recursion(HashSet offset is used to compensate + int offset = gc.v_liveData.data_totalDemand_kW.size() - liveWeekSize; + int gcLiveDatasetIndex = i + offset; + + if(gcLiveDatasetIndex < 0){ // If dataset index does not exist for this GridConnection -> skip this index + continue; + } for (OL_EnergyCarriers EC_consumption : gc.v_liveData.activeConsumptionEnergyCarriers) { - fm_demand_kW.addFlow( EC_consumption, gc.v_liveData.dsm_liveDemand_kW.get(EC_consumption).getY(i)); + fm_demand_kW.addFlow( EC_consumption, gc.v_liveData.dsm_liveDemand_kW.get(EC_consumption).getY(gcLiveDatasetIndex)); } for (OL_EnergyCarriers EC_production : gc.v_liveData.activeProductionEnergyCarriers) { - fm_supply_kW.addFlow( EC_production, gc.v_liveData.dsm_liveSupply_kW.get(EC_production).getY(i)); + fm_supply_kW.addFlow( EC_production, gc.v_liveData.dsm_liveSupply_kW.get(EC_production).getY(gcLiveDatasetIndex)); } for (OL_AssetFlowCategories AC : gc.v_liveAssetsMetaData.activeAssetFlows) { - fm_currentAssetFlows_kW.addFlow(AC, gc.v_liveData.dsm_liveAssetFlows_kW.get(AC).getY(i)); + fm_currentAssetFlows_kW.addFlow(AC, gc.v_liveData.dsm_liveAssetFlows_kW.get(AC).getY(gcLiveDatasetIndex)); } - electricityDemandCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacityDemand_kW.getY(i); - electricitySupplyCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacitySupply_kW.getY(i); - netLoadLiveWeek_kW += gc.v_liveData.data_liveElectricityBalance_kW.getY(i); + electricityDemandCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacityDemand_kW.getY(gcLiveDatasetIndex); + electricitySupplyCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacitySupply_kW.getY(gcLiveDatasetIndex); + netLoadLiveWeek_kW += gc.v_liveData.data_liveElectricityBalance_kW.getY(gcLiveDatasetIndex); //Other - batteryStoredEnergyLiveWeek_MWh += gc.v_liveData.data_batteryStoredEnergyLiveWeek_MWh.getY(i); + batteryStoredEnergyLiveWeek_MWh += gc.v_liveData.data_batteryStoredEnergyLiveWeek_MWh.getY(gcLiveDatasetIndex); } for (OL_EnergyCarriers EC_consumption : v_liveData.activeConsumptionEnergyCarriers) { diff --git a/_alp/Agents/GridConnection/Code/Functions.xml b/_alp/Agents/GridConnection/Code/Functions.xml index 2d6e6631..b43b6295 100644 --- a/_alp/Agents/GridConnection/Code/Functions.xml +++ b/_alp/Agents/GridConnection/Code/Functions.xml @@ -164,7 +164,7 @@ - + VOID double 1698854861644 From a169322c83cf955a08cade0107ea7fb3fc4fb0bb Mon Sep 17 00:00:00 2001 From: Luc-Sol Date: Mon, 22 Jun 2026 18:42:40 +0200 Subject: [PATCH 2/3] Bigger rework of dataset creation in livedata (WIP) - Created a class DataSetConstructor with a static method to get a new liveweek data set, which has values zero for all timesteps in the past. - In the class J_LiveData the method clearLiveDataSets has been renamed to resetLiveDataSets to conform with the naming of AnyLogic's DataSet - The old method resetLiveDataSets has been renamed to createNewLiveDataSets, it uses the above mentioned constructor. - Removed f_initializeDataSets in the GridConnection as this function is now a one-liner call on liveData. - f_collectGridConnectionLiveData in the EnergyCoop has been refactored. The previous commits in this PR solved the bug, but the .get(0) was still bothering me. The loop size and time variables are now calculated from information from J_TimeParameters and J_TimeVariables - Renamed the helper functions f_addConsumptionEnergyCarrier, f_addProductionEnergyCarrier, f_addAssetFlow to specify AfterInitialization.. - TODO: Cleanup the timeParameters & timeVariables arguments and check for changes that effect other packages. --- Zero_engine.alpx | 7 +- _alp/Agents/EnergyCoop/Code/Functions.java | 127 ++++++++---------- _alp/Agents/EnergyModel/Code/Functions.java | 16 ++- .../Agents/GridConnection/Code/Functions.java | 112 ++++++--------- _alp/Agents/GridConnection/Code/Functions.xml | 30 +---- _alp/Classes/Class.DataSetConstructor.java | 23 ++++ _alp/Classes/Class.J_DataSetMap.java | 6 + _alp/Classes/Class.J_LiveData.java | 66 +++------ 8 files changed, 171 insertions(+), 216 deletions(-) create mode 100644 _alp/Classes/Class.DataSetConstructor.java diff --git a/Zero_engine.alpx b/Zero_engine.alpx index baa6578c..67608eb5 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -1,7 +1,7 @@ 1658477103134 @@ -2229,6 +2229,11 @@ LARGE_CONNECTION (grootverbruik, > 3x80) 1776078970513 + + 1782137734965 + + 1764938574089 + com.anylogic.libraries.modules.markup_descriptors diff --git a/_alp/Agents/EnergyCoop/Code/Functions.java b/_alp/Agents/EnergyCoop/Code/Functions.java index 6e01200f..6ae57b90 100644 --- a/_alp/Agents/EnergyCoop/Code/Functions.java +++ b/_alp/Agents/EnergyCoop/Code/Functions.java @@ -1295,81 +1295,68 @@ HashSet f_getAllChildCustomerGridConnections_recursion(HashSet gcList = findAll(f_getAllChildMemberGridConnections(), gc -> gc.v_isActive); -int liveWeekSize = gcList.get(0).v_liveData.data_gridCapacityDemand_kW.size(); - -for (int i=0; i < liveWeekSize; i++){ - - double timeAxisValue = gcList.get(0).v_liveData.data_gridCapacityDemand_kW.getX(i); // we get the X value from a random dataset - - // Demand - J_FlowsMap fm_demand_kW = new J_FlowsMap(); - J_ValueMap fm_currentAssetFlows_kW = new J_ValueMap(OL_AssetFlowCategories.class); - - double electricityDemandCapacityLiveWeek_kW = 0; - double electricitySupplyCapacityLiveWeek_kW = 0; - double netLoadLiveWeek_kW = 0; - - double districtHeatingDemandLiveWeek_kW = 0; - - // Supply - J_FlowsMap fm_supply_kW = new J_FlowsMap(); - - //Other - double batteryStoredEnergyLiveWeek_MWh = 0; - - for (GridConnection gc : gcList){ - // Certain GridConnections do not have full or same sized live datasets - // due to pause functionality or GC creation during runtime -> offset is used to compensate - int offset = gc.v_liveData.data_totalDemand_kW.size() - liveWeekSize; - int gcLiveDatasetIndex = i + offset; - - if(gcLiveDatasetIndex < 0){ // If dataset index does not exist for this GridConnection -> skip this index - continue; - } - for (OL_EnergyCarriers EC_consumption : gc.v_liveData.activeConsumptionEnergyCarriers) { - fm_demand_kW.addFlow( EC_consumption, gc.v_liveData.dsm_liveDemand_kW.get(EC_consumption).getY(gcLiveDatasetIndex)); - } - for (OL_EnergyCarriers EC_production : gc.v_liveData.activeProductionEnergyCarriers) { - fm_supply_kW.addFlow( EC_production, gc.v_liveData.dsm_liveSupply_kW.get(EC_production).getY(gcLiveDatasetIndex)); - } - for (OL_AssetFlowCategories AC : gc.v_liveAssetsMetaData.activeAssetFlows) { - fm_currentAssetFlows_kW.addFlow(AC, gc.v_liveData.dsm_liveAssetFlows_kW.get(AC).getY(gcLiveDatasetIndex)); - } - - electricityDemandCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacityDemand_kW.getY(gcLiveDatasetIndex); - electricitySupplyCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacitySupply_kW.getY(gcLiveDatasetIndex); - netLoadLiveWeek_kW += gc.v_liveData.data_liveElectricityBalance_kW.getY(gcLiveDatasetIndex); - - //Other - batteryStoredEnergyLiveWeek_MWh += gc.v_liveData.data_batteryStoredEnergyLiveWeek_MWh.getY(gcLiveDatasetIndex); - } - - for (OL_EnergyCarriers EC_consumption : v_liveData.activeConsumptionEnergyCarriers) { - v_liveData.dsm_liveDemand_kW.get(EC_consumption).add(timeAxisValue, roundToDecimal(fm_demand_kW.get(EC_consumption), 3)); - } - for (OL_EnergyCarriers EC_production : v_liveData.activeProductionEnergyCarriers) { - v_liveData.dsm_liveSupply_kW.get(EC_production).add(timeAxisValue, roundToDecimal(fm_supply_kW.get(EC_production), 3)); - } - - for (OL_AssetFlowCategories AC : fm_currentAssetFlows_kW.keySet()) { - v_liveData.dsm_liveAssetFlows_kW.get(AC).add(timeAxisValue, roundToDecimal(fm_currentAssetFlows_kW.get(AC), 3)); - } - - v_liveData.data_gridCapacityDemand_kW.add(timeAxisValue, electricityDemandCapacityLiveWeek_kW); - v_liveData.data_gridCapacitySupply_kW.add(timeAxisValue, electricitySupplyCapacityLiveWeek_kW); - v_liveData.data_liveElectricityBalance_kW.add(timeAxisValue, netLoadLiveWeek_kW); - - //Stored - v_liveData.data_batteryStoredEnergyLiveWeek_MWh.add(timeAxisValue, batteryStoredEnergyLiveWeek_MWh); +if (gcList.isEmpty()) { + f_getTotalInstalledCapacityOfAssets_live(); + f_recalculateSOCDataSet_live(); + return; } +final int timeStepsInWeek = roundToInt(24*7 / energyModel.p_timeParameters.getTimeStep_h()); +final int liveWeekSize = min(energyModel.p_timeVariables.getTimeStepsElapsed(), timeStepsInWeek); + +final double startTime_h = energyModel.p_timeVariables.getAnyLogicTime_h() - liveWeekSize * energyModel.p_timeParameters.getTimeStep_h(); + +for (int i = 0; i < liveWeekSize; i++) { + // Variables for each timestep + J_FlowsMap fm_demand_kW = new J_FlowsMap(); + J_FlowsMap fm_supply_kW = new J_FlowsMap(); + J_ValueMap fm_currentAssetFlows_kW = new J_ValueMap(OL_AssetFlowCategories.class); + + double electricityDemandCapacityLiveWeek_kW = 0; + double electricitySupplyCapacityLiveWeek_kW = 0; + double netLoadLiveWeek_kW = 0; + double batteryStoredEnergyLiveWeek_MWh = 0; + + // For each timestep sum across all active child GridConnections + for (GridConnection gc : gcList) { + for (OL_EnergyCarriers EC_consumption : gc.v_liveData.activeConsumptionEnergyCarriers) { + fm_demand_kW.addFlow(EC_consumption, gc.v_liveData.dsm_liveDemand_kW.get(EC_consumption).getY(i)); + } + for (OL_EnergyCarriers EC_production : gc.v_liveData.activeProductionEnergyCarriers) { + fm_supply_kW.addFlow(EC_production, gc.v_liveData.dsm_liveSupply_kW.get(EC_production).getY(i)); + } + for (OL_AssetFlowCategories AC : gc.v_liveAssetsMetaData.activeAssetFlows) { + fm_currentAssetFlows_kW.addFlow(AC, gc.v_liveData.dsm_liveAssetFlows_kW.get(AC).getY(i)); + } + + electricityDemandCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacityDemand_kW.getY(i); + electricitySupplyCapacityLiveWeek_kW += gc.v_liveData.data_gridCapacitySupply_kW.getY(i); + netLoadLiveWeek_kW += gc.v_liveData.data_liveElectricityBalance_kW.getY(i); + batteryStoredEnergyLiveWeek_MWh += gc.v_liveData.data_batteryStoredEnergyLiveWeek_MWh.getY(i); + } + + // Write aggregated timestep results into the EnergyCooperative's own live datasets + double timeAxisValue = startTime_h + i * energyModel.p_timeParameters.getTimeStep_h(); + + for (OL_EnergyCarriers EC_consumption : v_liveData.activeConsumptionEnergyCarriers) { + v_liveData.dsm_liveDemand_kW.get(EC_consumption).add(timeAxisValue, roundToDecimal(fm_demand_kW.get(EC_consumption), 3)); + } + for (OL_EnergyCarriers EC_production : v_liveData.activeProductionEnergyCarriers) { + v_liveData.dsm_liveSupply_kW.get(EC_production).add(timeAxisValue, roundToDecimal(fm_supply_kW.get(EC_production), 3)); + } + for (OL_AssetFlowCategories AC : fm_currentAssetFlows_kW.keySet()) { + v_liveData.dsm_liveAssetFlows_kW.get(AC).add(timeAxisValue, roundToDecimal(fm_currentAssetFlows_kW.get(AC), 3)); + } + + v_liveData.data_gridCapacityDemand_kW.add(timeAxisValue, electricityDemandCapacityLiveWeek_kW); + v_liveData.data_gridCapacitySupply_kW.add(timeAxisValue, electricitySupplyCapacityLiveWeek_kW); + v_liveData.data_liveElectricityBalance_kW.add(timeAxisValue, netLoadLiveWeek_kW); + v_liveData.data_batteryStoredEnergyLiveWeek_MWh.add(timeAxisValue, batteryStoredEnergyLiveWeek_MWh); +} -//Calculate cumulative asset capacities f_getTotalInstalledCapacityOfAssets_live(); - -//Recalculate SOC ts for energycoop +// Depends on fully populated datasets above — must stay at the end f_recalculateSOCDataSet_live(); - /*ALCODEEND*/} double f_rapidRunDataLogging(J_TimeVariables timeVariables) diff --git a/_alp/Agents/EnergyModel/Code/Functions.java b/_alp/Agents/EnergyModel/Code/Functions.java index 26946658..1f380bbb 100644 --- a/_alp/Agents/EnergyModel/Code/Functions.java +++ b/_alp/Agents/EnergyModel/Code/Functions.java @@ -559,10 +559,10 @@ ArrayList f_getActiveGridConnections() // Initialize all agents in the correct order, creating all connections. What about setting initial values? And how about repeated simulations? f_buildGridNodeTree(); -c_gridConnections.forEach(GC -> GC.f_initialize(p_timeParameters)); +c_gridConnections.forEach(GC -> GC.f_initialize(p_timeParameters, p_timeVariables)); // Only relevant for deserialisation: -c_pausedGridConnections.forEach(GC -> GC.f_initialize(p_timeParameters)); +c_pausedGridConnections.forEach(GC -> GC.f_initialize(p_timeParameters, p_timeVariables)); pop_connectionOwners.forEach(CO -> CO.f_initialize()); pop_energyCoops.forEach(EC -> EC.f_initialize(p_timeParameters)); // Not yet robust when there is no supplier initialized! @@ -1004,7 +1004,7 @@ EnergyCoop f_addProductionEnergyCarrier(OL_EnergyCarriers EC) v_liveData.connectionMetaData = v_liveConnectionMetaData; v_liveData.assetsMetaData = v_liveAssetsMetaData;*/ -v_liveData.resetLiveDatasets(p_timeParameters); +v_liveData.createNewLiveDataSets(p_timeParameters, p_timeVariables); fm_currentProductionFlows_kW = new J_FlowsMap(); fm_currentConsumptionFlows_kW = new J_FlowsMap(); @@ -1179,15 +1179,17 @@ Date f_getDate() double f_clearAllLiveDatasets() {/*ALCODESTART::1758619851984*/ +// Note: We don't call createNewLiveDataSets on the LiveData, that creates new references which would require the results UI to reload. + //Energy Model -v_liveData.clearLiveDatasets(); +v_liveData.resetLiveDatasets(); //Energy Coops -pop_energyCoops.forEach(EC -> EC.v_liveData.clearLiveDatasets()); +pop_energyCoops.forEach(EC -> EC.v_liveData.resetLiveDatasets()); //GridConnections -c_gridConnections.forEach(GC -> GC.v_liveData.clearLiveDatasets()); -c_pausedGridConnections.forEach(GC -> GC.v_liveData.clearLiveDatasets()); +c_gridConnections.forEach(GC -> GC.v_liveData.resetLiveDatasets()); +c_pausedGridConnections.forEach(GC -> GC.v_liveData.resetLiveDatasets()); /*ALCODEEND*/} double f_initializeEngineAfterLoad() diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java index 40c98443..0d59d752 100644 --- a/_alp/Agents/GridConnection/Code/Functions.java +++ b/_alp/Agents/GridConnection/Code/Functions.java @@ -167,7 +167,7 @@ else if(j_ea instanceof J_EAFlex j_eaFlex){ } /*ALCODEEND*/} -double f_initialize(J_TimeParameters timeParameters) +double f_initialize(J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1698854861644*/ if (v_liveConnectionMetaData.getPhysicalCapacity_kW() < 0) { throw new RuntimeException("Exception: GridConnection " + p_gridConnectionID + " has negative physical connection capacity!"); @@ -223,8 +223,7 @@ else if (j_ea.getEAType() == OL_EnergyAssetType.WINDMILL) { // Initializing Live Data Class v_liveAssetsMetaData.updateActiveAssetData(new ArrayList<>(List.of(this))); - -f_initializeDataSets(timeParameters); +v_liveData.createNewLiveDataSets(timeParameters, timeVariables); /*ALCODEEND*/} @@ -491,19 +490,10 @@ else if (flowPacket.flowsMap.get(EC) > 0){ } //Initialize datasets for all EC and AssetFlowCategories and clear all. - f_initializeDataSets(energyModel.p_timeParameters); - v_liveData.clearLiveDatasets(); + v_liveData.createNewLiveDataSets(energyModel.p_timeParameters, timeVariables); } /*ALCODEEND*/} -double f_initializeDataSets(J_TimeParameters timeParameters) -{/*ALCODESTART::1730728785333*/ -v_liveData.dsm_liveDemand_kW.createEmptyDataSets(v_liveData.activeConsumptionEnergyCarriers, (int)(168 / timeParameters.getTimeStep_h())); -v_liveData.dsm_liveSupply_kW.createEmptyDataSets(v_liveData.activeProductionEnergyCarriers, (int)(168 / timeParameters.getTimeStep_h())); -v_liveData.dsm_liveAssetFlows_kW.createEmptyDataSets(v_liveData.assetsMetaData.activeAssetFlows, (int)(168 / timeParameters.getTimeStep_h())); - -/*ALCODEEND*/} - double f_startAfterDeserialisation(J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1753348699140*/ fm_currentProductionFlows_kW = new J_FlowsMap(); @@ -585,73 +575,54 @@ OL_GridConnectionHeatingType f_getCurrentHeatingType() /*ALCODEEND*/} -EnergyCoop f_addConsumptionEnergyCarrier(OL_EnergyCarriers EC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) +EnergyCoop f_addConsumptionEnergyCarrierAfterInitialization(OL_EnergyCarriers EC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1754380684463*/ -v_liveData.activeEnergyCarriers.add(EC); -v_liveData.activeConsumptionEnergyCarriers.add(EC); - -DataSet dsDemand = new DataSet( (int)(168 / timeParameters.getTimeStep_h()) ); - -double endTime = timeVariables.getAnyLogicTime_h(); -double startTime = max(0, timeVariables.getAnyLogicTime_h() - 168); - -for (double t = startTime; t <= endTime; t += timeParameters.getTimeStep_h()) { - dsDemand.add( t, 0); +if (!v_liveData.activeConsumptionEnergyCarriers.contains(EC)) { + v_liveData.activeEnergyCarriers.add(EC); + v_liveData.activeConsumptionEnergyCarriers.add(EC); + DataSet dsDemand = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); + v_liveData.dsm_liveDemand_kW.put( EC, dsDemand); + + //Add energy carrier also to coops/aggregators & energymodel + energyModel.f_addConsumptionEnergyCarrier(EC); + c_parentCoops.forEach(x -> x.f_addConsumptionEnergyCarrier(EC, timeParameters, timeVariables)); } -v_liveData.dsm_liveDemand_kW.put( EC, dsDemand); - /*ALCODEEND*/} -EnergyCoop f_addProductionEnergyCarrier(OL_EnergyCarriers EC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) +EnergyCoop f_addProductionEnergyCarrierAfterInitialization(OL_EnergyCarriers EC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1754380684465*/ -v_liveData.activeEnergyCarriers.add(EC); -v_liveData.activeProductionEnergyCarriers.add(EC); - -DataSet dsSupply = new DataSet( (int)(168 / timeParameters.getTimeStep_h()) ); - -double endTime = timeVariables.getAnyLogicTime_h(); -double startTime = max(0, timeVariables.getAnyLogicTime_h() - 168); - -for (double t = startTime; t <= endTime; t += timeParameters.getTimeStep_h()) { - dsSupply.add( t, 0); +if (!v_liveData.activeProductionEnergyCarriers.contains(EC)) { + v_liveData.activeEnergyCarriers.add(EC); + v_liveData.activeProductionEnergyCarriers.add(EC); + DataSet dsSupply = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); + v_liveData.dsm_liveSupply_kW.put( EC, dsSupply); + + //Add energy carrier also to coops/aggregators & energymodel + energyModel.f_addProductionEnergyCarrier(EC); + c_parentCoops.forEach(x -> x.f_addProductionEnergyCarrier(EC, timeParameters, timeVariables)); } -v_liveData.dsm_liveSupply_kW.put( EC, dsSupply); - /*ALCODEEND*/} -EnergyCoop f_addAssetFlow(OL_AssetFlowCategories AC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) +EnergyCoop f_addAssetFlowAfterInitialization(OL_AssetFlowCategories AC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1754380684467*/ if (!v_liveAssetsMetaData.activeAssetFlows.contains(AC)) { v_liveAssetsMetaData.activeAssetFlows.add(AC); - DataSet dsAsset = new DataSet( (int)(168 / timeParameters.getTimeStep_h()) ); - - double endTime = timeVariables.getAnyLogicTime_h(); - double startTime = max(0, timeVariables.getAnyLogicTime_h() - 168); - - for (double t = startTime; t <= endTime; t += timeParameters.getTimeStep_h()) { - dsAsset.add( t, 0); - } + DataSet dsAsset = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); v_liveData.dsm_liveAssetFlows_kW.put( AC, dsAsset); if (AC == OL_AssetFlowCategories.batteriesChargingPower_kW) { // also add batteriesDischarging! v_liveAssetsMetaData.activeAssetFlows.add(OL_AssetFlowCategories.batteriesDischargingPower_kW); - dsAsset = new DataSet( (int)(168 / timeParameters.getTimeStep_h()) ); - for (double t = startTime; t <= endTime; t += timeParameters.getTimeStep_h()) { - dsAsset.add( t, 0); - } + dsAsset = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); v_liveData.dsm_liveAssetFlows_kW.put( OL_AssetFlowCategories.batteriesDischargingPower_kW, dsAsset); } if (AC == OL_AssetFlowCategories.V2GPower_kW && !v_liveAssetsMetaData.activeAssetFlows.contains(OL_AssetFlowCategories.evChargingPower_kW)) { // also add evCharging! v_liveAssetsMetaData.activeAssetFlows.add(OL_AssetFlowCategories.evChargingPower_kW); - dsAsset = new DataSet( (int)(168 / timeParameters.getTimeStep_h()) ); - for (double t = startTime; t <= endTime; t += timeParameters.getTimeStep_h()) { - dsAsset.add( t, 0); - } + dsAsset = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); v_liveData.dsm_liveAssetFlows_kW.put( OL_AssetFlowCategories.evChargingPower_kW, dsAsset); } - //Add asset flow also to aggregators + //Add asset flow also to coops/aggregators & energymodel c_parentCoops.forEach(x -> x.f_addAssetFlow(AC, timeParameters, timeVariables)); energyModel.f_addAssetFlow(AC); } @@ -660,9 +631,10 @@ EnergyCoop f_addAssetFlow(OL_AssetFlowCategories AC,J_TimeParameters timeParamet double f_activateV2GChargingMode(boolean enableV2G,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1754582754934*/ if(energyModel.b_isInitialized){ + // Why is the setter also inside the if statement? ~Luc 22/06/26 p_energyManagement.setV2GActive(enableV2G); if (enableV2G){ - f_addAssetFlow(OL_AssetFlowCategories.V2GPower_kW, timeParameters, timeVariables); + f_addAssetFlowAfterInitialization(OL_AssetFlowCategories.V2GPower_kW, timeParameters, timeVariables); } } /*ALCODEEND*/} @@ -722,26 +694,24 @@ EnergyCoop f_addAssetFlow(OL_AssetFlowCategories AC,J_TimeParameters timeParamet {/*ALCODESTART::1756977865503*/ for (OL_EnergyCarriers EC : j_ea.getActiveConsumptionEnergyCarriers()) { if (!v_liveData.activeConsumptionEnergyCarriers.contains(EC)) { - v_liveData.activeConsumptionEnergyCarriers.add(EC); - v_liveData.activeEnergyCarriers.add(EC); if (energyModel.b_isInitialized && v_isActive) { - f_addConsumptionEnergyCarrier(EC, timeParameters, timeVariables); - //Add EC to energyModel - energyModel.f_addConsumptionEnergyCarrier(EC); - c_parentCoops.forEach(x -> x.f_addConsumptionEnergyCarrier(EC, timeParameters, timeVariables)); + f_addConsumptionEnergyCarrierAfterInitialization(EC, timeParameters, timeVariables); + } + else { + v_liveData.activeConsumptionEnergyCarriers.add(EC); + v_liveData.activeEnergyCarriers.add(EC); } } } for (OL_EnergyCarriers EC : j_ea.getActiveProductionEnergyCarriers()) { if (!v_liveData.activeProductionEnergyCarriers.contains(EC)) { - v_liveData.activeProductionEnergyCarriers.add(EC); - v_liveData.activeEnergyCarriers.add(EC); if (energyModel.b_isInitialized && v_isActive) { - f_addProductionEnergyCarrier(EC, timeParameters, timeVariables); - //Add EC to energyModel - energyModel.f_addProductionEnergyCarrier(EC); - c_parentCoops.forEach(x -> x.f_addProductionEnergyCarrier(EC, timeParameters, timeVariables)); + f_addProductionEnergyCarrierAfterInitialization(EC, timeParameters, timeVariables); + } + else { + v_liveData.activeProductionEnergyCarriers.add(EC); + v_liveData.activeEnergyCarriers.add(EC); } } } @@ -749,7 +719,7 @@ EnergyCoop f_addAssetFlow(OL_AssetFlowCategories AC,J_TimeParameters timeParamet if(j_ea.assetFlowCategory != null &&!v_liveAssetsMetaData.activeAssetFlows.contains(j_ea.assetFlowCategory)) { // add live dataset OL_AssetFlowCategories AC = j_ea.assetFlowCategory; if (energyModel.b_isInitialized && v_isActive) { - f_addAssetFlow(AC, timeParameters, timeVariables); + f_addAssetFlowAfterInitialization(AC, timeParameters, timeVariables); } else{ v_liveAssetsMetaData.activeAssetFlows.add(AC); diff --git a/_alp/Agents/GridConnection/Code/Functions.xml b/_alp/Agents/GridConnection/Code/Functions.xml index b43b6295..aec81daf 100644 --- a/_alp/Agents/GridConnection/Code/Functions.xml +++ b/_alp/Agents/GridConnection/Code/Functions.xml @@ -182,6 +182,10 @@ + + + + @@ -365,26 +369,6 @@ - - VOID - double - 1730728785333 - - 950 - 70 - - false - true - true - - - - - - VOID double @@ -470,7 +454,7 @@ VOID EnergyCoop 1754380684463 - + 1325 67 - - VOID - EnergyCoop - 1754380102233 - - 1438 - 536 - - false - true - true - - - - - - - - - - - - - - - - VOID - EnergyCoop - 1754380102235 - - 1438 - 556 - - false - true - true - - - - - - - - - - - - - - - - VOID - EnergyCoop - 1754380102237 - - 1438 - 576 - - false - true - true - - - - - - - - - - - - - - VOID double diff --git a/_alp/Agents/EnergyModel/Code/Functions.java b/_alp/Agents/EnergyModel/Code/Functions.java index 1f380bbb..076c6beb 100644 --- a/_alp/Agents/EnergyModel/Code/Functions.java +++ b/_alp/Agents/EnergyModel/Code/Functions.java @@ -637,27 +637,27 @@ List f_getNonRootGridNodes() {/*ALCODESTART::1722590514591*/ for (GridConnection GC : UtilityConnections) { if (!GC.v_isActive) { - GC.f_setActive(false, p_timeVariables); + GC.f_setActive(false, p_timeParameters, p_timeVariables); } } for (GridConnection GC : EnergyProductionSites) { if (!GC.v_isActive) { - GC.f_setActive(false, p_timeVariables); + GC.f_setActive(false,p_timeParameters, p_timeVariables); } } for (GridConnection GC : EnergyConversionSites) { if (!GC.v_isActive) { - GC.f_setActive(false, p_timeVariables); + GC.f_setActive(false, p_timeParameters, p_timeVariables); } } for (GridConnection GC : GridBatteries) { if (!GC.v_isActive) { - GC.f_setActive(false, p_timeVariables); + GC.f_setActive(false, p_timeParameters, p_timeVariables); } } for (GridConnection GC : PublicChargers) { if (!GC.v_isActive) { - GC.f_setActive(false, p_timeVariables); + GC.f_setActive(false, p_timeParameters, p_timeVariables); } } /*ALCODEEND*/} @@ -734,7 +734,7 @@ EnergyCoop f_addEnergyCoop(ArrayList gcList,J_TimeParameters tim return energyCoop; /*ALCODEEND*/} -EnergyCoop f_removeEnergyCoop(EnergyCoop energyCoop,J_TimeVariables timeVariables) +EnergyCoop f_removeEnergyCoop(EnergyCoop energyCoop,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1739972940581*/ // Connect GCs, connectionOwners and energyCoop and gather data for(Agent CO : energyCoop.c_coopCustomers){ @@ -757,7 +757,7 @@ EnergyCoop f_removeEnergyCoop(EnergyCoop energyCoop,J_TimeVariables timeVariable if(GC instanceof GCGridBattery && GC.f_getBatteryManagement() instanceof J_BatteryManagementPeakShaving && ((J_BatteryManagementPeakShaving)GC.f_getBatteryManagement()).getTargetType() == OL_ResultScope.ENERGYCOOP){ ((J_BatteryManagementPeakShaving)GC.f_getBatteryManagement()).setTarget(null); ((J_BatteryManagementPeakShaving)GC.f_getBatteryManagement()).setTargetType( OL_ResultScope.ENERGYCOOP ); - GC.f_setActive(false, timeVariables); + GC.f_setActive(false, timeParameters, timeVariables); } } @@ -767,24 +767,6 @@ EnergyCoop f_removeEnergyCoop(EnergyCoop energyCoop,J_TimeVariables timeVariable /*ALCODEEND*/} -EnergyCoop f_addConsumptionEnergyCarrier(OL_EnergyCarriers EC) -{/*ALCODESTART::1740056275008*/ -if (!v_liveData.activeConsumptionEnergyCarriers.contains(EC)) { - v_liveData.activeEnergyCarriers.add(EC); - v_liveData.activeConsumptionEnergyCarriers.add(EC); - - DataSet dsDemand = new DataSet( (int)(168 / p_timeParameters.getTimeStep_h()) ); - - double endTime = p_timeVariables.getAnyLogicTime_h(); - double startTime = max(0, p_timeVariables.getAnyLogicTime_h() - 168); - - for (double t = startTime; t <= endTime; t += p_timeParameters.getTimeStep_h()) { - dsDemand.add( t, 0); - } - v_liveData.dsm_liveDemand_kW.put( EC, dsDemand); -} -/*ALCODEEND*/} - double f_updateActiveAssetsMetaData() {/*ALCODESTART::1741710906926*/ @@ -803,24 +785,6 @@ EnergyCoop f_addConsumptionEnergyCarrier(OL_EnergyCarriers EC) /*ALCODEEND*/} -EnergyCoop f_addProductionEnergyCarrier(OL_EnergyCarriers EC) -{/*ALCODESTART::1746021439807*/ -if (!v_liveData.activeProductionEnergyCarriers.contains(EC)) { - v_liveData.activeEnergyCarriers.add(EC); - v_liveData.activeProductionEnergyCarriers.add(EC); - - DataSet dsSupply = new DataSet( (int)(168 / p_timeParameters.getTimeStep_h()) ); - - double endTime = p_timeVariables.getAnyLogicTime_h(); - double startTime = max(0, p_timeVariables.getAnyLogicTime_h() - 168); - - for (double t = startTime; t <= endTime; t += p_timeParameters.getTimeStep_h()) { - dsSupply.add( t, 0); - } - v_liveData.dsm_liveSupply_kW.put( EC, dsSupply); -} -/*ALCODEEND*/} - double f_updateAmbientDependentAssets() {/*ALCODESTART::1751886925823*/ // Update environmental conditions for relevant energy assets @@ -1105,40 +1069,6 @@ Pair f_getPeakWeekDataSets() /*ALCODEEND*/} -EnergyCoop f_addAssetFlow(OL_AssetFlowCategories AC) -{/*ALCODESTART::1754379679149*/ -if (!v_liveAssetsMetaData.activeAssetFlows.contains(AC)) { - v_liveAssetsMetaData.activeAssetFlows.add(AC); - - DataSet dsAsset = new DataSet( (int)(168 / p_timeParameters.getTimeStep_h()) ); - - double endTime = p_timeVariables.getAnyLogicTime_h(); - double startTime = max(0, p_timeVariables.getAnyLogicTime_h() - 168); - - for (double t = startTime; t <= endTime; t += p_timeParameters.getTimeStep_h()) { - dsAsset.add( t, 0); - } - v_liveData.dsm_liveAssetFlows_kW.put( AC, dsAsset); - - if (AC == OL_AssetFlowCategories.batteriesChargingPower_kW) { // also add batteriesDischarging! - dsAsset = new DataSet( (int)(168 / p_timeParameters.getTimeStep_h()) ); - - for (double t = startTime; t <= endTime; t += p_timeParameters.getTimeStep_h()) { - dsAsset.add( t, 0); - } - v_liveData.dsm_liveAssetFlows_kW.put( OL_AssetFlowCategories.batteriesDischargingPower_kW, dsAsset); - } - if (AC == OL_AssetFlowCategories.V2GPower_kW && !v_liveAssetsMetaData.activeAssetFlows.contains(OL_AssetFlowCategories.evChargingPower_kW)) { // also add evCharging! - dsAsset = new DataSet( (int)(168 / p_timeParameters.getTimeStep_h()) ); - - for (double t = startTime; t <= endTime; t += p_timeParameters.getTimeStep_h()) { - dsAsset.add( t, 0); - } - v_liveData.dsm_liveAssetFlows_kW.put( OL_AssetFlowCategories.evChargingPower_kW, dsAsset); - } -} -/*ALCODEEND*/} - List f_getGridConnectionsCollectionPointer() {/*ALCODESTART::1754908171225*/ return this.c_gridConnections; diff --git a/_alp/Agents/EnergyModel/Code/Functions.xml b/_alp/Agents/EnergyModel/Code/Functions.xml index 87f69c35..e9e05ab5 100644 --- a/_alp/Agents/EnergyModel/Code/Functions.xml +++ b/_alp/Agents/EnergyModel/Code/Functions.xml @@ -460,28 +460,12 @@ - - + + - - - - VOID - EnergyCoop - 1740056275008 - - 1640 - 420 - - false - true - true - - + + @@ -501,26 +485,6 @@ true - - VOID - EnergyCoop - 1746021439807 - - 1640 - 440 - - false - true - true - - - - - - VOID double @@ -585,26 +549,6 @@ true - - VOID - EnergyCoop - 1754379679149 - - 1640 - 460 - - false - true - true - - - - - - RETURNS_VALUE List<GridConnection> diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java index 0d59d752..a851b329 100644 --- a/_alp/Agents/GridConnection/Code/Functions.java +++ b/_alp/Agents/GridConnection/Code/Functions.java @@ -383,7 +383,7 @@ else if (flowPacket.flowsMap.get(EC) > 0){ timeVariables); /*ALCODEEND*/} -double f_setActive(boolean setActive,J_TimeVariables timeVariables) +double f_setActive(boolean setActive,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1722584668566*/ if((energyModel.c_pausedGridConnections.contains(this) && !setActive) || (!energyModel.c_pausedGridConnections.contains(this) && setActive)){ @@ -447,8 +447,8 @@ else if (flowPacket.flowsMap.get(EC) > 0){ v_isActive = setActive; // v_isActive must be true before calling updateActiveAssetData! v_liveAssetsMetaData.updateActiveAssetData(new ArrayList<>(List.of(this))); - v_liveAssetsMetaData.activeAssetFlows.forEach(x->energyModel.f_addAssetFlow(x)); - v_liveAssetsMetaData.activeAssetFlows.forEach(x-> c_parentCoops.forEach(coop -> coop.f_addAssetFlow(x, energyModel.p_timeParameters, timeVariables))); + v_liveAssetsMetaData.activeAssetFlows.forEach(AFC -> energyModel.getLiveData().addAssetFlowCaterogy(AFC, energyModel.b_isInitialized, timeParameters, timeVariables)); + v_liveAssetsMetaData.activeAssetFlows.forEach(AFC -> c_parentCoops.forEach(coop -> coop.getLiveData().addAssetFlowCaterogy(AFC, energyModel.b_isInitialized, timeParameters, timeVariables))); // update GN parents' wind / solar totals (will be wrong if you changed your totals while paused) p_parentNodeElectric.f_updateTotalInstalledProductionAssets(OL_EnergyAssetType.PHOTOVOLTAIC, v_liveAssetsMetaData.totalInstalledPVPower_kW, true); @@ -490,7 +490,7 @@ else if (flowPacket.flowsMap.get(EC) > 0){ } //Initialize datasets for all EC and AssetFlowCategories and clear all. - v_liveData.createNewLiveDataSets(energyModel.p_timeParameters, timeVariables); + v_liveData.createNewLiveDataSets(timeParameters, timeVariables); } /*ALCODEEND*/} @@ -575,67 +575,13 @@ OL_GridConnectionHeatingType f_getCurrentHeatingType() /*ALCODEEND*/} -EnergyCoop f_addConsumptionEnergyCarrierAfterInitialization(OL_EnergyCarriers EC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) -{/*ALCODESTART::1754380684463*/ -if (!v_liveData.activeConsumptionEnergyCarriers.contains(EC)) { - v_liveData.activeEnergyCarriers.add(EC); - v_liveData.activeConsumptionEnergyCarriers.add(EC); - DataSet dsDemand = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); - v_liveData.dsm_liveDemand_kW.put( EC, dsDemand); - - //Add energy carrier also to coops/aggregators & energymodel - energyModel.f_addConsumptionEnergyCarrier(EC); - c_parentCoops.forEach(x -> x.f_addConsumptionEnergyCarrier(EC, timeParameters, timeVariables)); -} -/*ALCODEEND*/} - -EnergyCoop f_addProductionEnergyCarrierAfterInitialization(OL_EnergyCarriers EC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) -{/*ALCODESTART::1754380684465*/ -if (!v_liveData.activeProductionEnergyCarriers.contains(EC)) { - v_liveData.activeEnergyCarriers.add(EC); - v_liveData.activeProductionEnergyCarriers.add(EC); - DataSet dsSupply = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); - v_liveData.dsm_liveSupply_kW.put( EC, dsSupply); - - //Add energy carrier also to coops/aggregators & energymodel - energyModel.f_addProductionEnergyCarrier(EC); - c_parentCoops.forEach(x -> x.f_addProductionEnergyCarrier(EC, timeParameters, timeVariables)); -} -/*ALCODEEND*/} - -EnergyCoop f_addAssetFlowAfterInitialization(OL_AssetFlowCategories AC,J_TimeParameters timeParameters,J_TimeVariables timeVariables) -{/*ALCODESTART::1754380684467*/ -if (!v_liveAssetsMetaData.activeAssetFlows.contains(AC)) { - v_liveAssetsMetaData.activeAssetFlows.add(AC); - - DataSet dsAsset = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); - v_liveData.dsm_liveAssetFlows_kW.put( AC, dsAsset); - - if (AC == OL_AssetFlowCategories.batteriesChargingPower_kW) { // also add batteriesDischarging! - v_liveAssetsMetaData.activeAssetFlows.add(OL_AssetFlowCategories.batteriesDischargingPower_kW); - dsAsset = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); - v_liveData.dsm_liveAssetFlows_kW.put( OL_AssetFlowCategories.batteriesDischargingPower_kW, dsAsset); - } - if (AC == OL_AssetFlowCategories.V2GPower_kW && !v_liveAssetsMetaData.activeAssetFlows.contains(OL_AssetFlowCategories.evChargingPower_kW)) { // also add evCharging! - v_liveAssetsMetaData.activeAssetFlows.add(OL_AssetFlowCategories.evChargingPower_kW); - dsAsset = DataSetConstructor.getNewLiveWeekDataSet(timeParameters, timeVariables); - v_liveData.dsm_liveAssetFlows_kW.put( OL_AssetFlowCategories.evChargingPower_kW, dsAsset); - } - - //Add asset flow also to coops/aggregators & energymodel - c_parentCoops.forEach(x -> x.f_addAssetFlow(AC, timeParameters, timeVariables)); - energyModel.f_addAssetFlow(AC); -} -/*ALCODEEND*/} - double f_activateV2GChargingMode(boolean enableV2G,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1754582754934*/ -if(energyModel.b_isInitialized){ - // Why is the setter also inside the if statement? ~Luc 22/06/26 - p_energyManagement.setV2GActive(enableV2G); - if (enableV2G){ - f_addAssetFlowAfterInitialization(OL_AssetFlowCategories.V2GPower_kW, timeParameters, timeVariables); - } +p_energyManagement.setV2GActive(enableV2G); +if (enableV2G){ + v_liveData.addAssetFlowCaterogy(OL_AssetFlowCategories.V2GPower_kW, energyModel.b_isInitialized, timeParameters, timeVariables); + energyModel.getLiveData().addAssetFlowCaterogy(OL_AssetFlowCategories.V2GPower_kW, energyModel.b_isInitialized, timeParameters, timeVariables); + c_parentCoops.forEach(coop -> coop.getLiveData().addAssetFlowCaterogy(OL_AssetFlowCategories.V2GPower_kW, energyModel.b_isInitialized, timeParameters, timeVariables)); } /*ALCODEEND*/} @@ -692,39 +638,11 @@ EnergyCoop f_addAssetFlowAfterInitialization(OL_AssetFlowCategories AC,J_TimePar double f_addEnergyCarriersAndAssetCategoriesFromEA(J_EA j_ea,J_TimeParameters timeParameters,J_TimeVariables timeVariables) {/*ALCODESTART::1756977865503*/ -for (OL_EnergyCarriers EC : j_ea.getActiveConsumptionEnergyCarriers()) { - if (!v_liveData.activeConsumptionEnergyCarriers.contains(EC)) { - if (energyModel.b_isInitialized && v_isActive) { - f_addConsumptionEnergyCarrierAfterInitialization(EC, timeParameters, timeVariables); - } - else { - v_liveData.activeConsumptionEnergyCarriers.add(EC); - v_liveData.activeEnergyCarriers.add(EC); - } - } -} +v_liveData.addEnergyCarriersAndAssetFlowCategoriesFromEA(j_ea, energyModel.b_isInitialized, timeParameters, timeVariables); -for (OL_EnergyCarriers EC : j_ea.getActiveProductionEnergyCarriers()) { - if (!v_liveData.activeProductionEnergyCarriers.contains(EC)) { - if (energyModel.b_isInitialized && v_isActive) { - f_addProductionEnergyCarrierAfterInitialization(EC, timeParameters, timeVariables); - } - else { - v_liveData.activeProductionEnergyCarriers.add(EC); - v_liveData.activeEnergyCarriers.add(EC); - } - } -} - -if(j_ea.assetFlowCategory != null &&!v_liveAssetsMetaData.activeAssetFlows.contains(j_ea.assetFlowCategory)) { // add live dataset - OL_AssetFlowCategories AC = j_ea.assetFlowCategory; - if (energyModel.b_isInitialized && v_isActive) { - f_addAssetFlowAfterInitialization(AC, timeParameters, timeVariables); - } - else{ - v_liveAssetsMetaData.activeAssetFlows.add(AC); - } -} +//Add energy carrier/afc also to coops/aggregators & energymodel +energyModel.getLiveData().addEnergyCarriersAndAssetFlowCategoriesFromEA(j_ea, energyModel.b_isInitialized, timeParameters, timeVariables); +c_parentCoops.forEach(coop -> coop.getLiveData().addEnergyCarriersAndAssetFlowCategoriesFromEA(j_ea, energyModel.b_isInitialized, timeParameters, timeVariables)); /*ALCODEEND*/} double f_setChargingManagement(I_ChargingManagement chargingManagement) diff --git a/_alp/Agents/GridConnection/Code/Functions.xml b/_alp/Agents/GridConnection/Code/Functions.xml index aec81daf..8ab6b22a 100644 --- a/_alp/Agents/GridConnection/Code/Functions.xml +++ b/_alp/Agents/GridConnection/Code/Functions.xml @@ -146,7 +146,7 @@ 1692799608559 950 - 95 + 75 - - VOID - EnergyCoop - 1754380684463 - - 1325 - 67 - - false - true - true - - - - - - - - - - - - - - - - VOID - EnergyCoop - 1754380684465 - - 1325 - 87 - - false - true - true - - - - - - - - - - - - - - - - VOID - EnergyCoop - 1754380684467 - - 1325 - 107 - - false - true - true - - - - - - - - - - - - - - VOID double @@ -588,8 +508,8 @@ double 1756977865503 - 1310 - 40 + 970 + 175