diff --git a/_alp/Agents/UI_Tabs/EmbeddedObjects.xml b/_alp/Agents/UI_Tabs/EmbeddedObjects.xml index 5c31394..16b4ac3 100644 --- a/_alp/Agents/UI_Tabs/EmbeddedObjects.xml +++ b/_alp/Agents/UI_Tabs/EmbeddedObjects.xml @@ -75,13 +75,13 @@ - + - + - + true diff --git a/_alp/Agents/Zero_Interface/Code/Functions.java b/_alp/Agents/Zero_Interface/Code/Functions.java index 811815d..4a44ddc 100644 --- a/_alp/Agents/Zero_Interface/Code/Functions.java +++ b/_alp/Agents/Zero_Interface/Code/Functions.java @@ -383,6 +383,33 @@ else if(b.p_annotation != null){ //alle panden met meerdere adressen hebben op dit moment (16-7-24) dezelfde functie(s) voor ieder adres, dus dit is op dit moment zinloos //f_listFunctions(); +f_updateCustomGCSolarfarmSettings(); +f_updateCustomGCWindfarmSettings(); +f_updateCustomGCGridBatterySettings(); + +boolean anyCustomSettingsOpen = false; +if (!c_selectedGridConnections.isEmpty()) { + GridConnection selectedGC = c_selectedGridConnections.get(0); + if(selectedGC instanceof GCEnergyProduction){ + if (v_clickedObjectType == OL_GISObjectType.SOLARFARM && c_customSolarfarmGCs.contains((GCEnergyProduction)selectedGC)) { + anyCustomSettingsOpen = true; + } + else if (v_clickedObjectType == OL_GISObjectType.WINDFARM && c_customWindfarmGCs.contains((GCEnergyProduction)selectedGC)) { + anyCustomSettingsOpen = true; + } + } + else if (selectedGC instanceof GCGridBattery){ + if (v_clickedObjectType == OL_GISObjectType.BATTERY && c_customGridBatteryGCs.contains((GCGridBattery)selectedGC)) { + anyCustomSettingsOpen = true; + } + } +} + +if (anyCustomSettingsOpen) { + uI_Tabs_presentation.setVisible(false); +} else { + uI_Tabs_presentation.setVisible(true); +} /*ALCODEEND*/} double f_deselectPreviousSelect() @@ -431,6 +458,9 @@ else if (previousClickedObjectType == OL_GISObjectType.BUILDING || v_customEnergyCoop = null; } } + +// RESTORE tab visibility when closing/deselecting settings +uI_Tabs_presentation.setVisible(true); /*ALCODEEND*/} double f_connectResultsUI() @@ -3810,6 +3840,74 @@ List f_getSelectedChartTypes_Energy() else if(b_inManualFilterSelectionMode){ f_selectManualFilteredGC(clickx, clicky); } +else if (b_addCustomSolarfarmGC || b_addCustomWindfarmGC || b_addCustomGridBatteryGC) { + if (v_customGCLatitude == 0 && v_customGCLongitude == 0) { + // Step 1: Set location + v_customGCLatitude = clickx; // Assuming clickx is lat or lon depending on map orientation + v_customGCLongitude = clicky; + txt_addCustomGCToMapTaskInstruction.setText("Kies een trafo op de kaart"); + traceln("Location set. Now click on a transformer (GridNode) to connect the energy asset."); + f_deselectPreviousSelect(); + return; + } else { + // Step 2: Select transformer + GridNode clickedGN = null; + for (GridNode GN : energyModel.pop_gridNodes) { + if (GN.gisRegion != null && GN.gisRegion.contains(clickx, clicky) && GN.gisRegion.isVisible()) { + clickedGN = GN; + break; + } + } + + if (clickedGN != null) { + if (b_addCustomSolarfarmGC){ + f_addCustomSolarfarmGC(v_customGCLatitude, v_customGCLongitude, clickedGN); + b_addCustomSolarfarmGC = false; + } else if (b_addCustomWindfarmGC){ + f_addCustomWindfarmGC(v_customGCLatitude, v_customGCLongitude, clickedGN); + b_addCustomWindfarmGC = false; + } else if (b_addCustomGridBatteryGC){ + f_addCustomGridBatteryGC(v_customGCLatitude, v_customGCLongitude, clickedGN); + b_addCustomGridBatteryGC = false; + } + v_customGCLatitude = 0; + v_customGCLongitude = 0; + return; + } else { + traceln("Please click on a valid transformer (GridNode)."); + return; + } + } +} +else if (b_removeCustomGC) { + // Group all GIS objects to check for the click + List allGISObjects = new ArrayList<>(); + for(GIS_Building b : energyModel.pop_GIS_Buildings) { + allGISObjects.add(b); + } + for(GIS_Object object : energyModel.pop_GIS_Objects){ + allGISObjects.add(object); + } + for (GIS_Object GISObject : allGISObjects) { + if (GISObject.gisRegion != null && GISObject.gisRegion.contains(clickx, clicky) && GISObject.gisRegion.isVisible()) { + if (GISObject.c_containedGridConnections.size() > 0) { + GridConnection gc = GISObject.c_containedGridConnections.get(0); + + // Only allow deletion of specific energy asset types + if (gc instanceof GCEnergyProduction || gc instanceof GCGridBattery) { + f_removeCustomGC(gc); + b_removeCustomGC = false; // Reset mode after deletion + traceln("Removed the energy asset: " + gc.p_gridConnectionID); + return; + } + } + } + } + // If the user clicks elsewhere, cancel the deletion mode + b_removeCustomGC = false; + traceln("Deletion mode cancelled."); + return; +} else{ if (uI_Tabs.pop_tabEHub.size() > 0 && uI_Tabs.pop_tabEHub.get(0).b_inCapacitySharingSelectionMode) { uI_Tabs.pop_tabEHub.get(0).f_checkGISRegion(clickx, clicky); @@ -3855,3 +3953,462 @@ else if (c_selectedFilterOptions.contains(OL_FilterOptionsGC.GRIDTOPOLOGY_SELECT uI_Results.f_updateResultsUI(c_selectedGridConnections.get(0)); /*ALCODEEND*/} +double f_addCustomSolarfarmGC(double lat,double lon,GridNode gn) +{/*ALCODESTART::1777995108231*/ +String id = "Custom_Solarfarm_" + v_customSolarfarmGCCounter++; + +// 0. Get existic sliderGC owner +ConnectionOwner owner = f_getSliderOwnerForCustomGC(OL_EnergyAssetType.PHOTOVOLTAIC); +if(owner == null){ + throw new RuntimeException("No owner made your custom EA type!"); +} + +// 1. Create the GCEnergyProduction agent +GCEnergyProduction solarpark = energyModel.add_EnergyProductionSites(); +solarpark.set_p_gridConnectionID(id); +solarpark.set_p_ownerID(owner.p_actorID); +solarpark.set_p_owner(owner); +solarpark.p_parentNodeElectricID = gn.p_gridNodeID; +solarpark.p_isSliderGC = true; // This affects the slider range + setValue + +// 2. Set capacity +double defaultCapacity_kW = energyModel.avgc_data.p_avgSolarFieldPower_kWppha; +solarpark.v_liveConnectionMetaData.setCapacities_kW(0, defaultCapacity_kW, defaultCapacity_kW); +solarpark.v_liveConnectionMetaData.setCapacitiesKnown(true, true, true); + +// 3. Initialize GridConnection internals and set active +solarpark.f_initialize(energyModel.p_timeParameters); +solarpark.f_setActive(true, energyModel.p_timeVariables); + +// 4. Create the energy asset +J_EAProduction pvAsset = new J_EAProduction(solarpark, OL_EnergyAssetType.PHOTOVOLTAIC, "Custom PV", OL_EnergyCarriers.ELECTRICITY, defaultCapacity_kW, energyModel.p_timeParameters, energyModel.pp_PVProduction35DegSouth_fr); + +// 5. Create the GIS Object +GIS_Object area = f_createAndLinkGISObject(solarpark, id, OL_GISObjectType.SOLARFARM, v_solarParkColor, v_solarParkLineColor, lat, lon); + +// 6. Update collections, sliders and legend +c_customSolarfarmGCs.add(solarpark); +if (!c_modelActiveSpecialGISObjects.contains(area.p_GISObjectType)) { + c_modelActiveSpecialGISObjects.add(area.p_GISObjectType); +} +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} +f_refreshLegend(); + +traceln("Successfully added custom solarfarm at " + lat + ", " + lon + " connected to " + gn.p_gridNodeID); +/*ALCODEEND*/} + +double f_removeCustomGC(GridConnection gc) +{/*ALCODESTART::1777995108233*/ +gc.f_setActive(false, energyModel.p_timeVariables); + +// 1. Remove energy assets +for(J_EA ea : new ArrayList<>(gc.c_energyAssets)) { + ea.removeEnergyAsset(); +} + +// 2. Remove GIS Object +OL_GISObjectType removedGISType = null; +for (GIS_Object obj : new ArrayList<>(gc.c_connectedGISObjects)) { + removedGISType = obj.p_GISObjectType; + obj.gisRegion.setVisible(false); + energyModel.remove_pop_GIS_Objects(obj); +} + +// 3. Remove from collections +energyModel.c_pausedGridConnections.remove(gc); +if (gc instanceof GCEnergyProduction) { + energyModel.remove_EnergyProductionSites((GCEnergyProduction)gc); + if(c_customSolarfarmGCs.contains((GCEnergyProduction)gc)){ + c_customSolarfarmGCs.remove(gc); + } + else if(c_customWindfarmGCs.contains((GCEnergyProduction)gc)){ + c_customWindfarmGCs.remove(gc); + } +} else if (gc instanceof GCGridBattery) { + energyModel.remove_GridBatteries((GCGridBattery)gc); + c_customGridBatteryGCs.remove((GCGridBattery)gc); +} + +// 4. Refresh slider + legend to account for changes +if (removedGISType != null) { + boolean typeExists = false; + // Verify if any assets of this type still exist in the simulation + for (GIS_Object obj : energyModel.pop_GIS_Objects) { + if (obj.p_GISObjectType == removedGISType && obj.gisRegion != null && obj.gisRegion.isVisible()) { + typeExists = true; + break; + } + } + if (!typeExists) { + c_modelActiveSpecialGISObjects.remove(removedGISType); + } +} +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} +f_refreshLegend(); +/*ALCODEEND*/} + +double f_addCustomWindfarmGC(double lat,double lon,GridNode gn) +{/*ALCODESTART::1777995108235*/ +String id = "Custom_Windfarm_" + v_customWindfarmGCCounter++; + +// 0. Get existic sliderGC owner +ConnectionOwner owner = f_getSliderOwnerForCustomGC(OL_EnergyAssetType.WINDMILL); +if(owner == null){ + throw new RuntimeException("No owner made your custom EA type!"); +} + +// 1. Create the GCEnergyProduction agent +GCEnergyProduction windpark = energyModel.add_EnergyProductionSites(); +windpark.set_p_gridConnectionID(id); +windpark.set_p_ownerID(owner.p_actorID); +windpark.set_p_owner(owner); +windpark.p_parentNodeElectricID = gn.p_gridNodeID; +windpark.p_isSliderGC = true; // This affects the slider range + setValue + +// 2. Set capacity +double defaultCapacity_kW = 2000; +windpark.v_liveConnectionMetaData.setCapacities_kW(0, defaultCapacity_kW, defaultCapacity_kW); +windpark.v_liveConnectionMetaData.setCapacitiesKnown(true, true, true); + +// 3. Initialize GridConnection internals and set active +windpark.f_initialize(energyModel.p_timeParameters); +windpark.f_setActive(true, energyModel.p_timeVariables); + +// 4. Create the Energy Asset +J_EAProduction windAsset = new J_EAProduction(windpark, OL_EnergyAssetType.WINDMILL, "Custom Windpark", OL_EnergyCarriers.ELECTRICITY, defaultCapacity_kW, energyModel.p_timeParameters, energyModel.pp_windProduction_fr); + +// 5. Create the GIS Object +GIS_Object area = f_createAndLinkGISObject(windpark, id, OL_GISObjectType.WINDFARM, v_windFarmColor, v_windFarmLineColor, lat, lon); + +// 6. Update collections, sliders and legend +c_customWindfarmGCs.add(windpark); +if (!c_modelActiveSpecialGISObjects.contains(area.p_GISObjectType)) { + c_modelActiveSpecialGISObjects.add(area.p_GISObjectType); +} +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} +f_refreshLegend(); + +traceln("Successfully added custom windfarm at " + lat + ", " + lon + " connected to " + gn.p_gridNodeID); +/*ALCODEEND*/} + +double f_addCustomGridBatteryGC(double lat,double lon,GridNode gn) +{/*ALCODESTART::1777995108237*/ +String id = "Custom_Grid_Battery_" + v_customGridBatteryGCCounter++; + +// 0. Get existic sliderGC owner +ConnectionOwner owner = f_getSliderOwnerForCustomGC(OL_EnergyAssetType.STORAGE_ELECTRIC); +if(owner == null){ + throw new RuntimeException("No owner made your custom EA type!"); +} + +// 1. Create the GCGridBattery agent +GCGridBattery battery = energyModel.add_GridBatteries(); +battery.set_p_gridConnectionID(id); +battery.set_p_ownerID(owner.p_actorID); +battery.set_p_owner(owner); +battery.p_parentNodeElectricID = gn.p_gridNodeID; +battery.p_isSliderGC = true; // This affects the slider range + setValue + +// 2. Set capacity +double defaultCapacity_kW = 1000; +double defaultStorageCapacity_kWh = 2*defaultCapacity_kW; +battery.v_liveConnectionMetaData.setCapacities_kW(defaultCapacity_kW, defaultCapacity_kW, defaultCapacity_kW); +battery.v_liveConnectionMetaData.setCapacitiesKnown(true, true, true); + +// 3. Initialize GridConnection internals and set active +battery.f_initialize(energyModel.p_timeParameters); +battery.f_setActive(true, energyModel.p_timeVariables); + +// 4. Create the energy asset + pick default operation mode management class +J_EAStorageElectric batteryAsset = new J_EAStorageElectric(battery, defaultCapacity_kW, defaultStorageCapacity_kWh, 0.5, energyModel.p_timeParameters); +I_BatteryManagement batteryAlgorithm = new J_BatteryManagementSelfConsumptionGridNode(battery, energyModel.p_timeParameters); +battery.f_setBatteryManagement(batteryAlgorithm); + +// 5. Create GIS Object +GIS_Object area = f_createAndLinkGISObject(battery, id, OL_GISObjectType.BATTERY, v_batteryColor, v_batteryLineColor, lat, lon); + +// 6. Update collections, sliders and legend +c_customGridBatteryGCs.add(battery); +if (!c_modelActiveSpecialGISObjects.contains(area.p_GISObjectType)) { + c_modelActiveSpecialGISObjects.add(area.p_GISObjectType); +} +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} +f_refreshLegend(); + +traceln("Successfully added custom grid battery at " + lat + ", " + lon + " connected to " + gn.p_gridNodeID); +/*ALCODEEND*/} + +double f_updateCustomGCSolarfarmSettings() +{/*ALCODESTART::1778162093872*/ +if (c_selectedGridConnections.isEmpty()) { + return; +} + +GridConnection selectedGC = c_selectedGridConnections.get(0); +if (!(selectedGC instanceof GCEnergyProduction) || !c_customSolarfarmGCs.contains(selectedGC)) { + return; +} + +GCEnergyProduction gc = (GCEnergyProduction) selectedGC; +J_EAProduction pvAsset = (J_EAProduction) gc.c_productionAssets.get(0); + +double currentCapacity_kW = pvAsset.getCapacityElectric_kW(); +double currentCapacity_ha = currentCapacity_kW / energyModel.avgc_data.p_avgSolarFieldPower_kWppha; + +// Setup capacity ha slider +sl_customGCSolarfarmInstalledCapacity_ha.setRange(0.1, 10); +sl_customGCSolarfarmInstalledCapacity_ha.setValue(currentCapacity_ha, false); // false prevents triggering ActionCode + +// Setup capacity kW slider +sl_customGCSolarfarmInstalledCapacity_kW.setRange((int)(0.1*energyModel.avgc_data.p_avgSolarFieldPower_kWppha), (int)(10*energyModel.avgc_data.p_avgSolarFieldPower_kWppha)); +sl_customGCSolarfarmInstalledCapacity_kW.setValue(currentCapacity_kW, false); + +// Setup contracted capacity slider +sl_customGCSolarfarmContractedCapacity_kW.setRange(0, currentCapacity_kW); +sl_customGCSolarfarmContractedCapacity_kW.setValue(gc.v_liveConnectionMetaData.getContractedFeedinCapacity_kW(), false); + +// Setup curtailment checkbox +boolean hasCurtailment = gc.f_isAssetManagementActive(I_CurtailManagement.class); +cb_customGCSolarfarmCurtailment.setSelected(hasCurtailment, false); + +/*ALCODEEND*/} + +double f_updateCustomGCWindfarmSettings() +{/*ALCODESTART::1778241627082*/ +if (c_selectedGridConnections.isEmpty()) { + return; +} + +GridConnection selectedGC = c_selectedGridConnections.get(0); +if (!(selectedGC instanceof GCEnergyProduction) || !c_customWindfarmGCs.contains(selectedGC)) { + return; +} + +GCEnergyProduction gc = (GCEnergyProduction) selectedGC; +J_EAProduction windAsset = (J_EAProduction) gc.c_productionAssets.get(0); + +double currentCapacity_MW = windAsset.getCapacityElectric_kW()/1000; + +// Setup capacity MW slider +sl_customGCWindfarmInstalledCapacity_MW.setRange(0.1, 10); +sl_customGCWindfarmInstalledCapacity_MW.setValue(currentCapacity_MW, false); // false prevents triggering ActionCode + +// Setup contracted capacity slider +sl_customGCWindfarmContractedCapacity_MW.setRange(0, currentCapacity_MW); +sl_customGCWindfarmContractedCapacity_MW.setValue(gc.v_liveConnectionMetaData.getContractedFeedinCapacity_kW()/1000, false); + +// Setup curtailment checkbox +boolean hasCurtailment = gc.f_isAssetManagementActive(I_CurtailManagement.class); +cb_customGCWindfarmCurtailment.setSelected(hasCurtailment, false); + +/*ALCODEEND*/} + +double f_updateCustomGCGridBatterySettings() +{/*ALCODESTART::1778281342673*/ +if (c_selectedGridConnections.isEmpty()) { + return; +} + +GridConnection selectedGC = c_selectedGridConnections.get(0); +if (!(selectedGC instanceof GCGridBattery) || !c_customGridBatteryGCs.contains(selectedGC)) { + return; +} + +GCGridBattery gc = (GCGridBattery) selectedGC; +J_EAStorageElectric batteryAsset = (J_EAStorageElectric)gc.c_storageAssets.get(0); + +double currentCapacity_MWh = batteryAsset.getStorageCapacity_kWh()/1000; +double currentCapacity_MW = batteryAsset.getCapacityElectric_kW()/1000; + +// Setup capacity MW slider +sl_customGCGridBatteryInstalledCapacity_MWh.setRange(0.1, 5); +sl_customGCGridBatteryInstalledCapacity_MWh.setValue(currentCapacity_MWh, false); + +// Setup contracted capacity slider +sl_customGCGridBatteryInstalledCapacity_MW.setRange(0.05, 2.5); +sl_customGCGridBatteryInstalledCapacity_MW.setValue(currentCapacity_MW, false); + +// Battery Management selection +I_BatteryManagement currentBatteryManagement = gc.f_getBatteryManagement(); +String currentBMS_str = "Zelfverbruik"; // Default fallback + +if (currentBatteryManagement instanceof J_BatteryManagementSelfConsumptionGridNode) { + currentBMS_str = "Zelfverbruik"; +} else if (currentBatteryManagement instanceof J_BatteryManagementPeakShaving) { + currentBMS_str = "Peak shaving"; +} else if (currentBatteryManagement instanceof J_BatteryManagementPrice) { + currentBMS_str = "Prijssturing"; +} +cb_customGCGridBatteryAlgorithm.setValue(currentBMS_str, false); +/*ALCODEEND*/} + +ConnectionOwner f_getSliderOwnerForCustomGC(OL_EnergyAssetType eaType) +{/*ALCODESTART::1778854379860*/ +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + tabElectricity tabElec = uI_Tabs.pop_tabElectricity.get(0); + for (GridConnection gc : tabElec.c_electricityTabEASliderGCs) { + if (eaType == OL_EnergyAssetType.PHOTOVOLTAIC || eaType == OL_EnergyAssetType.WINDMILL) { + if (gc instanceof GCEnergyProduction) { + for (J_EAProduction ea : ((GCEnergyProduction)gc).c_productionAssets) { + if (ea.getEAType() == eaType) { + return gc.p_owner; + } + } + } + } else if (eaType == OL_EnergyAssetType.STORAGE_ELECTRIC) { + if (gc instanceof GCGridBattery) { + return gc.p_owner; + } + } + } +} +return null; +/*ALCODEEND*/} + +GIS_Object f_createAndLinkGISObject(GridConnection gc,String id,OL_GISObjectType gisType,Color fillColor,Color lineColor,double lat,double lon) +{/*ALCODESTART::1778855159263*/ +GIS_Object area = energyModel.add_pop_GIS_Objects(); +area.p_id = id; +area.p_GISObjectType = gisType; +area.p_latitude = lat; +area.p_longitude = lon; + +// 1. Calculate physical footprint size (area in m2) based on capacity +double area_m2 = f_calculateGISObjectArea(gc, gisType); + +// 2. Generate square polygon coordinates and assign to region +double[] polyCoords = f_calculateSquareCoordinates(lat, lon, area_m2); +area.gisRegion = f_createGISObject(polyCoords); + +// 3. Add to collections +area.c_containedGridConnections.add(gc); +gc.c_connectedGISObjects.add(area); + +// 4. Apply styling +area.set_p_defaultFillColor(fillColor); +area.set_p_defaultLineColor(lineColor); +area.set_p_defaultLineWidth(v_energyAssetLineWidth); +f_styleAreas(area); + +return area; +/*ALCODEEND*/} + +GIS_Object f_refreshLegend() +{/*ALCODESTART::1778856248260*/ +// Hide the maximum possible special legend items before rebuilding to prevent UI overlap +for (int i = 1; i <= 10; i++) { + try { + Pair legendShapes = f_getNextSpecialLegendShapes(i); + if (legendShapes != null && legendShapes.getFirst() != null && legendShapes.getSecond() != null) { + legendShapes.getFirst().setVisible(false); + legendShapes.getSecond().setVisible(false); + } + } catch (Exception e) { + break; // Stop if we run out of defined legend shapes in the UI + } +} +// Rebuild the legend using existing functionality +f_initializeLegend(); +/*ALCODEEND*/} + +double f_updateGISObjectSize(GridConnection gc) +{/*ALCODESTART::1778950448168*/ +for (GIS_Object area : gc.c_connectedGISObjects) { + if (area.p_GISObjectType == OL_GISObjectType.SOLARFARM || area.p_GISObjectType == OL_GISObjectType.WINDFARM || area.p_GISObjectType == OL_GISObjectType.BATTERY) { + + // 1. Calculate physical footprint size (area in m2) based on capacity + double area_m2 = f_calculateGISObjectArea(gc, area.p_GISObjectType); + + // 2. Generate square polygon coordinates + double[] polyCoords = f_calculateSquareCoordinates(area.p_latitude, area.p_longitude, area_m2); + + // 3. Clean up the previously drawn polygon region + if (area.gisRegion != null) { + area.gisRegion.remove(); + } + + // 4. Create new polygon region + area.gisRegion = f_createGISObject(polyCoords); + + // 5. Re-apply styling (colors/visibility) + f_styleAreas(area); + } +} +/*ALCODEEND*/} + +double f_calculateGISObjectArea(GridConnection gc,OL_GISObjectType gisType) +{/*ALCODESTART::1778997814360*/ +/** + * Calculates the footprint area in square meters (m2) of a custom energy asset based on its capacity. + * + * - Solar farm: 1 hectare per 'p_avgSolarFieldPower_kWppha' kW + * - Wind farm: 1 hectare per 5 MW (5000 kW) capacity + * - Battery: 1 hectare per 100 MWh storage capacity (100 m2 per MWh) + */ + +double area_m2 = 100.0; // Default fallback size +if (gc instanceof GCEnergyProduction prodGC) { + if (gisType == OL_GISObjectType.SOLARFARM) { + double capacity_kW = 0.0; + for (J_EAProduction asset : prodGC.c_productionAssets) { + if (asset.getEAType() == OL_EnergyAssetType.PHOTOVOLTAIC) { + capacity_kW += asset.getCapacityElectric_kW(); + } + } + double capacity_ha = capacity_kW / energyModel.avgc_data.p_avgSolarFieldPower_kWppha; + area_m2 = capacity_ha * 10000.0; + } + else if (gisType == OL_GISObjectType.WINDFARM) { + double capacity_kW = 0.0; + for (J_EAProduction asset : prodGC.c_productionAssets) { + if (asset.getEAType() == OL_EnergyAssetType.WINDMILL) { + capacity_kW += asset.getCapacityElectric_kW(); + } + } + double capacity_ha = (capacity_kW / 1000.0) / 5.0; // 5 MW per hectare + area_m2 = capacity_ha * 10000.0; + } +} +else if (gc instanceof GCGridBattery batteryGC) { + if (gisType == OL_GISObjectType.BATTERY) { + double capacity_MWh = batteryGC.p_batteryAsset.getStorageCapacity_kWh() / 1000.0; + double capacity_ha = capacity_MWh / 100.0; // 100 MWh per hectare + area_m2 = capacity_ha * 10000.0; + } + } +return area_m2; +/*ALCODEEND*/} + +double[] f_calculateSquareCoordinates(double lat,double lon,double area_m2) +{/*ALCODESTART::1778997955081*/ +/** + * Computes a list of double coordinates representing a perfectly square polygon centered + * at (lat, lon) with a physical area of 'area_m2' in square meters, correcting for local latitude "deformation". + */ + +double side_m = Math.sqrt(area_m2); +double halfSide_m = side_m / 2.0; + +// Earth conversion factors (approximate for localized areas) +double metersPerDegLat = 111320.0; +double metersPerDegLon = 111320.0 * Math.cos(Math.toRadians(lat)); + +double offsetLat = halfSide_m / metersPerDegLat; +double offsetLon = halfSide_m / metersPerDegLon; + +return new double[]{ + lat + offsetLat, lon - offsetLon, // Top-left + lat + offsetLat, lon + offsetLon, // Top-right + lat - offsetLat, lon + offsetLon, // Bottom-right + lat - offsetLat, lon - offsetLon // Bottom-left +}; +/*ALCODEEND*/} + diff --git a/_alp/Agents/Zero_Interface/Code/Functions.xml b/_alp/Agents/Zero_Interface/Code/Functions.xml index 35e242b..a930708 100644 --- a/_alp/Agents/Zero_Interface/Code/Functions.xml +++ b/_alp/Agents/Zero_Interface/Code/Functions.xml @@ -2754,4 +2754,308 @@ true + + VOID + double + 1777995108231 + + 60 + 1720 + + false + true + true + + + + + + + + + + + + + + + + VOID + double + 1777995108233 + + 60 + 1630 + + false + true + true + + + + + + + + VOID + double + 1777995108235 + + 60 + 1810 + + false + true + true + + + + + + + + + + + + + + + + VOID + double + 1777995108237 + + 60 + 1900 + + false + true + true + + + + + + + + + + + + + + + + VOID + double + 1778162093872 + + 2120 + -3100 + + false + true + true + + + + VOID + double + 1778241627082 + + 2120 + -3080 + + false + true + true + + + + VOID + double + 1778281342673 + + 2120 + -3060 + + false + true + true + + + + RETURNS_VALUE + ConnectionOwner + 1778854379860 + + 80 + 1930 + + false + true + true + + + + + + + + RETURNS_VALUE + GIS_Object + 1778855159263 + + 60 + 1960 + + false + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VOID + GIS_Object + 1778856248260 + + 1540 + 1550 + + false + true + true + + + + VOID + double + 1778950448168 + + 60 + 1980 + + false + true + true + + + + + + + + RETURNS_VALUE + double + 1778997814360 + + 80 + 2000 + + false + true + true + + + + + + + + + + + + RETURNS_VALUE + double[] + 1778997955081 + + 80 + 2020 + + false + true + true + + + + + + + + + + + + + + diff --git a/_alp/Agents/Zero_Interface/Levels/Level.level.xml b/_alp/Agents/Zero_Interface/Levels/Level.level.xml index fbe342e..9a13214 100644 --- a/_alp/Agents/Zero_Interface/Levels/Level.level.xml +++ b/_alp/Agents/Zero_Interface/Levels/Level.level.xml @@ -8351,4 +8351,1551 @@ else{ LEFT + + 1777996495522 + + 1080 + -2880 + + true + false + false + SHAPE_DRAW_2D3D + 960 + 500 + b_addCustomSolarfarmGC || b_addCustomWindfarmGC || b_addCustomGridBatteryGC || b_removeCustomGC + false + 0 + 0.0 + + + 1777996495524 + + -960 + -500 + + true + true + false + SHAPE_DRAW_2D3D + int clickblocker; + false + 0 + 10 + 1 + + null + SOLID + 410 + 980 + 0.0 + 16777215 + null + + + 1777996495526 + + -550 + -500 + + true + true + false + SHAPE_DRAW_2D3D + int clickblocker; + false + 0 + 10 + 1 + + null + SOLID + 1000 + 130 + 0.0 + 16777215 + null + + + 1777996495528 + + -550 + 250 + + true + true + false + SHAPE_DRAW_2D3D + int clickblocker; + false + 0 + 10 + 1 + + null + SOLID + 1000 + 230 + 0.0 + 16777215 + null + + + 1777996495530 + + 450 + -500 + + true + true + false + SHAPE_DRAW_2D3D + int clickblocker; + false + 0 + 10 + 1 + + null + SOLID + 510 + 980 + 0.0 + 16777215 + null + + + 1777996495532 + + -960 + -620 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 1 + + null + SOLID + 410 + 1200 + 0.0 + -1765752640 + v_forcedClickScreenColor + null + + + 1777996495534 + + -550 + -620 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 1 + + null + SOLID + 1000 + 250 + 0.0 + -1765752640 + v_forcedClickScreenColor + null + + + 1777996495536 + + -550 + 250 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 1 + + null + SOLID + 1000 + 330 + 0.0 + -1765752640 + v_forcedClickScreenColor + null + + + 1777996495538 + + 450 + -620 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 1 + + null + SOLID + 510 + 1200 + 0.0 + -1765752640 + v_forcedClickScreenColor + null + + + 1777996495548 + + 10 + -240 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + + + 1777996495562 + + -60 + -190 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + + + 1777996495564 + + -500 + -50 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 10 + 2 + -16777216 + null + SOLID + 1000 + 90 + 0.0 + -1 + null + 10 + + + 1777996495566 + + 0 + -35 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 48 + + + CENTER + + + + + 1777996495568 + + -820 + 630 + + true + true + false + SHAPE_DRAW_2D + v_customGCLatitude = 0; +v_customGCLongitude = 0; +b_addCustomSolarfarmGC = false; +b_addCustomWindfarmGC = false; +b_addCustomGridBatteryGC = false; +b_removeCustomGC = false; + false + 0 + 0.0 + + + 1777996495570 + + -90 + -30 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 10 + 3 + -2345659 + null + SOLID + 275 + 75 + 0.0 + -1 + null + 10 + + + 1777996495572 + + 48 + -10 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 28 + + + CENTER + + + + + + + + + 1778088271551 + + 2100 + -3500 + + true + false + false + SHAPE_DRAW_2D3D + 15 + 630 + v_clickedObjectType == OL_GISObjectType.SOLARFARM && !c_selectedGridConnections.isEmpty() && c_customSolarfarmGCs.contains((GCEnergyProduction)c_selectedGridConnections.get(0)) + false + 0 + 0.0 + + + 1778088176151 + + 0 + 0 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 3 + + null + SOLID + 370 + 350 + 0.0 + -32 + null + + + 1778088438360 + + 20 + 20 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 22 + + + LEFT + + + 1778088565568 + + 20 + 90 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778089224407 + + 245 + 90 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + sl_customGCSolarfarmInstalledCapacity_ha.getValue() + " ha" + + + 12 + + + RIGHT + + + false + 1778089224409 + + 260 + 85 + + true + true + false + SHAPE_DRAW_2D3D + + false + true + double installedCapacity_ha = sl_customGCSolarfarmInstalledCapacity_ha.getValue(); +double installedCapacity_kW = installedCapacity_ha * energyModel.avgc_data.p_avgSolarFieldPower_kWppha; + +// Sync sl_customGCSolarfarmInstalledCapacity_kW slider without triggering its action +sl_customGCSolarfarmInstalledCapacity_kW.setValue(installedCapacity_kW, false); + +GCEnergyProduction gc = (GCEnergyProduction)c_selectedGridConnections.get(0); +J_EAProduction pvAsset = (J_EAProduction)gc.c_productionAssets.get(0); + +// If needed, adjust the contracted capacity +double contractedCapacity_kW = sl_customGCSolarfarmContractedCapacity_kW.getValue(); +if (contractedCapacity_kW > installedCapacity_kW) { + contractedCapacity_kW = installedCapacity_kW; + sl_customGCSolarfarmContractedCapacity_kW.setValue(contractedCapacity_kW, false); +} +// Dynamically clamp the range of the contracted capacity slider +sl_customGCSolarfarmContractedCapacity_kW.setRange(0, installedCapacity_kW); + +// Update backend +pvAsset.setCapacityElectric_kW(installedCapacity_kW, gc); +gc.v_liveConnectionMetaData.setCapacities_kW(0, contractedCapacity_kW, installedCapacity_kW); + +// Update polygon size +f_updateGISObjectSize(gc); + +// Update the active instance of tabElectricity sliders +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + 0 + HORIZONTAL + 0.1 + false + + + + 1778157224958 + + 20 + 60 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + c_selectedGridConnections.isEmpty() ? "" : "Naam: " + c_selectedGridConnections.get(0).p_gridConnectionID + + + 12 + + + LEFT + + + 1778157755373 + + 245 + 120 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + sl_customGCSolarfarmInstalledCapacity_kW.getValue() + " kW" + + + 12 + + + RIGHT + + + false + 1778157791903 + + 260 + 115 + + true + true + false + SHAPE_DRAW_2D3D + + false + true + double installedCapacity_kW = sl_customGCSolarfarmInstalledCapacity_kW.getValue(); +double installedCapacity_ha = installedCapacity_kW / energyModel.avgc_data.p_avgSolarFieldPower_kWppha; + +// Sync sl_customEASolarfarmInstalledCapacity_ha slider without triggering its action +sl_customGCSolarfarmInstalledCapacity_ha.setValue(installedCapacity_ha, false); + +GCEnergyProduction gc = (GCEnergyProduction)c_selectedGridConnections.get(0); +J_EAProduction pvAsset = (J_EAProduction)gc.c_productionAssets.get(0); + +// If needed, adjust the contracted capacity +double contractedCapacity_kW = sl_customGCSolarfarmContractedCapacity_kW.getValue(); +if (contractedCapacity_kW > installedCapacity_kW) { + contractedCapacity_kW = installedCapacity_kW; + sl_customGCSolarfarmContractedCapacity_kW.setValue(contractedCapacity_kW, false); +} +// Dynamically clamp the range of the contracted capacity slider +sl_customGCSolarfarmContractedCapacity_kW.setRange(0, installedCapacity_kW); + +// Update backend +pvAsset.setCapacityElectric_kW(installedCapacity_kW, gc); +gc.v_liveConnectionMetaData.setCapacities_kW(0, contractedCapacity_kW, installedCapacity_kW); + +// Update polygon size +f_updateGISObjectSize(gc); + +// Update the active instance of tabElectricity sliders +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + 0 + HORIZONTAL + 100 + false + + + + 1778157960511 + + 20 + 150 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778158102891 + + 20 + 180 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778158258122 + + 245 + 150 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + sl_customGCSolarfarmContractedCapacity_kW.getValue() + " kW" + + + 12 + + + RIGHT + + + false + 1778158369195 + + 302 + 172 + + true + true + false + SHAPE_DRAW_2D3D + + false + -16777216 + true + GCEnergyProduction gc = (GCEnergyProduction) c_selectedGridConnections.get(0); +if (cb_customGCSolarfarmCurtailment.isSelected()) { + gc.f_setExternalAssetManagement(new J_CurtailManagementContractCapacity(gc, energyModel.p_timeParameters)); +} else { + gc.f_removeExternalAssetManagement(I_CurtailManagement.class); +} + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + + + false + + + + false + 1778158173095 + + 260 + 145 + + true + true + false + SHAPE_DRAW_2D3D + + false + true + double contractedCapacity_kW = sl_customGCSolarfarmContractedCapacity_kW.getValue(); + +// Update backend +GCEnergyProduction gc = (GCEnergyProduction) c_selectedGridConnections.get(0); +gc.v_liveConnectionMetaData.setCapacities_kW(0, contractedCapacity_kW, gc.v_liveConnectionMetaData.getPhysicalCapacity_kW()); + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + 0 + HORIZONTAL + 50 + false + + + + + + 1778241988036 + + 2500 + -3500 + + true + false + false + SHAPE_DRAW_2D3D + 15 + 630 + v_clickedObjectType == OL_GISObjectType.WINDFARM && !c_selectedGridConnections.isEmpty() && c_customWindfarmGCs.contains((GCEnergyProduction)c_selectedGridConnections.get(0)) + false + 0 + 0.0 + + + 1778241988038 + + 0 + 0 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 3 + + null + SOLID + 370 + 350 + 0.0 + -32 + null + + + 1778241988040 + + 20 + 20 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 22 + + + LEFT + + + 1778241988042 + + 20 + 90 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778241988044 + + 245 + 90 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + sl_customGCWindfarmInstalledCapacity_MW.getValue() + " MW" + + + 12 + + + RIGHT + + + false + 1778241988046 + + 260 + 85 + + true + true + false + SHAPE_DRAW_2D3D + + false + true + double installedCapacity_MW = sl_customGCWindfarmInstalledCapacity_MW.getValue(); + +GCEnergyProduction gc = (GCEnergyProduction)c_selectedGridConnections.get(0); +J_EAProduction windAsset = (J_EAProduction)gc.c_productionAssets.get(0); + +// If needed, adjust the contracted capacity +double contractedCapacity_MW = sl_customGCWindfarmContractedCapacity_MW.getValue(); +if (contractedCapacity_MW > installedCapacity_MW) { + contractedCapacity_MW = installedCapacity_MW; + sl_customGCWindfarmContractedCapacity_MW.setValue(contractedCapacity_MW, false); +} +// Dynamically clamp the range of the contracted capacity slider +sl_customGCWindfarmContractedCapacity_MW.setRange(0, installedCapacity_MW); + +// Update backend +windAsset.setCapacityElectric_kW(installedCapacity_MW*1000, gc); +gc.v_liveConnectionMetaData.setCapacities_kW(0, contractedCapacity_MW*1000, installedCapacity_MW*1000); + +// Update polygon size +f_updateGISObjectSize(gc); + +// Update the active instance of tabElectricity sliders +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + 0 + HORIZONTAL + 0.1 + false + + + + 1778241988050 + + 20 + 60 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + c_selectedGridConnections.isEmpty() ? "" : "Naam: " + c_selectedGridConnections.get(0).p_gridConnectionID + + + 12 + + + LEFT + + + 1778241988056 + + 20 + 120 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778241988058 + + 20 + 150 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778241988060 + + 245 + 120 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + sl_customGCWindfarmContractedCapacity_MW.getValue() + " MW" + + + 12 + + + RIGHT + + + false + 1778241988062 + + 302 + 142 + + true + true + false + SHAPE_DRAW_2D3D + + false + -16777216 + true + GCEnergyProduction gc = (GCEnergyProduction) c_selectedGridConnections.get(0); +if (cb_customGCWindfarmCurtailment.isSelected()) { + gc.f_setExternalAssetManagement(new J_CurtailManagementContractCapacity(gc, energyModel.p_timeParameters)); +} else { + gc.f_removeExternalAssetManagement(I_CurtailManagement.class); +} + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + + + false + + + + false + 1778241988064 + + 260 + 115 + + true + true + false + SHAPE_DRAW_2D3D + + false + true + double contractedCapacity_MW = sl_customGCWindfarmContractedCapacity_MW.getValue(); + +// Update backend +GCEnergyProduction gc = (GCEnergyProduction) c_selectedGridConnections.get(0); +gc.v_liveConnectionMetaData.setCapacities_kW(0, contractedCapacity_MW*1000, gc.v_liveConnectionMetaData.getPhysicalCapacity_kW()); + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + 0 + HORIZONTAL + 0.05 + false + + + + + + 1778278832476 + + 2900 + -3500 + + true + false + false + SHAPE_DRAW_2D3D + 15 + 630 + v_clickedObjectType == OL_GISObjectType.BATTERY && !c_selectedGridConnections.isEmpty() && c_customGridBatteryGCs.contains((GCGridBattery)c_selectedGridConnections.get(0)) + false + 0 + 0.0 + + + 1778278832478 + + 0 + 0 + + true + true + false + SHAPE_DRAW_2D3D + false + 0 + 10 + 3 + + null + SOLID + 370 + 350 + 0.0 + -32 + null + + + 1778278832480 + + 20 + 20 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 22 + + + LEFT + + + 1778278832482 + + 20 + 90 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778278832484 + + 245 + 90 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + sl_customGCGridBatteryInstalledCapacity_MWh.getValue() + " MWh" + + + 12 + + + RIGHT + + + false + 1778278832486 + + 260 + 85 + + true + true + false + SHAPE_DRAW_2D3D + + false + true + double installedCapacity_MWh = sl_customGCGridBatteryInstalledCapacity_MWh.getValue(); +double installedCapacity_MW = sl_customGCGridBatteryInstalledCapacity_MW.getValue(); + +if(installedCapacity_MW > 0.5*installedCapacity_MWh){ + installedCapacity_MW = 0.5*installedCapacity_MWh; + sl_customGCGridBatteryInstalledCapacity_MW.setValue(0.5*installedCapacity_MWh, false); +} +sl_customGCGridBatteryInstalledCapacity_MW.setRange(0.05, 0.5*installedCapacity_MWh); + +GCGridBattery gc = (GCGridBattery)c_selectedGridConnections.get(0); +J_EAStorageElectric batteryAsset = (J_EAStorageElectric)gc.c_storageAssets.get(0); + +// Update backend +batteryAsset.setStorageCapacity_kWh(installedCapacity_MWh*1000, gc); +batteryAsset.setCapacityElectric_kW(installedCapacity_MW*1000); +gc.v_liveConnectionMetaData.setCapacities_kW(installedCapacity_MW*1000, installedCapacity_MW*1000, installedCapacity_MW*1000); + +// Update polygon size +f_updateGISObjectSize(gc); + +// Update the active instance of tabElectricity sliders +if (!uI_Tabs.pop_tabElectricity.isEmpty()) { + uI_Tabs.pop_tabElectricity.get(0).f_updateSliders_Electricity(); +} + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + 0 + HORIZONTAL + 0.1 + false + + + + 1778278832490 + + 20 + 60 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + c_selectedGridConnections.isEmpty() ? "" : "Naam: " + c_selectedGridConnections.get(0).p_gridConnectionID + + + 12 + + + LEFT + + + 1778278832492 + + 245 + 120 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + sl_customGCGridBatteryInstalledCapacity_MW.getValue() + " MW" + + + 12 + + + RIGHT + + + false + 1778278832494 + + 260 + 115 + + true + true + false + SHAPE_DRAW_2D3D + + false + true + double installedCapacity_MW = sl_customGCGridBatteryInstalledCapacity_MW.getValue(); + +GCGridBattery gc = (GCGridBattery)c_selectedGridConnections.get(0); +J_EAStorageElectric batteryAsset = (J_EAStorageElectric)gc.c_storageAssets.get(0); + +batteryAsset.setCapacityElectric_kW(installedCapacity_MW*1000); +gc.v_liveConnectionMetaData.setCapacities_kW(installedCapacity_MW*1000, installedCapacity_MW*1000, installedCapacity_MW*1000); + +if (!b_runningMainInterfaceScenarios) f_setScenarioToCustom(); +f_resetSettings(); + + + 0 + HORIZONTAL + 0.05 + false + + + + 1778278832496 + + 20 + 150 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + 1778278946812 + + 20 + 120 + + true + true + false + SHAPE_DRAW_2D + false + 0 + 0.0 + -16777216 + + + + 12 + + + LEFT + + + false + 1778279933335 + + 220 + 150 + + true + true + false + SHAPE_DRAW_2D3D + + false + -1 + -16777216 + true + if (c_selectedGridConnections.isEmpty() || !(c_selectedGridConnections.get(0) instanceof GCGridBattery)) { + return; +} +GCGridBattery gc = (GCGridBattery)c_selectedGridConnections.get(0); +GridNode gn = gc.p_parentNodeElectric; +I_BatteryManagement batteryAlgorithm = null; + +switch(cb_customGCGridBatteryAlgorithm.getValue()){ + case "Zelfverbruik": + batteryAlgorithm = new J_BatteryManagementSelfConsumptionGridNode(gc, energyModel.p_timeParameters); + break; + case "Peak shaving": + batteryAlgorithm = new J_BatteryManagementPeakShaving(gc, energyModel.p_timeParameters); + ((J_BatteryManagementPeakShaving)batteryAlgorithm).setTarget(gn); + break; + case "Prijssturing": + batteryAlgorithm = new J_BatteryManagementPrice(gc, energyModel.p_timeParameters); + break; +} + +gc.f_setBatteryManagement(batteryAlgorithm); + + + + false + + + + false + + + + diff --git a/_alp/Agents/Zero_Interface/Variables.xml b/_alp/Agents/Zero_Interface/Variables.xml index c65c240..a5b30e5 100644 --- a/_alp/Agents/Zero_Interface/Variables.xml +++ b/_alp/Agents/Zero_Interface/Variables.xml @@ -2117,6 +2117,204 @@ + + 1777995108239 + + 60 + 1660 + + false + true + true + + + + + + + + + 1777995108241 + + 60 + 1570 + + false + true + true + + + + + + + + + 1777995108243 + + 60 + 1590 + + false + true + true + + + + + + + + + 1777995108245 + + 60 + 1680 + + false + true + true + + + + + + + + + 1777995108247 + + 60 + 1750 + + false + true + true + + + + + + + + + 1777995108249 + + 60 + 1770 + + false + true + true + + + + + + + + + 1777995108251 + + 60 + 1840 + + false + true + true + + + + + + + + + 1777995108253 + + 60 + 1860 + + false + true + true + + + + + + + + + 1777995108255 + + 60 + 1610 + + false + true + true + + + + + + + 1715858732720 @@ -3485,4 +3683,58 @@ OL_FilterOptionsGC.MANUAL_SELECTION, "Handmatige selectie" String + + 1777995108215 + + 60 + 1700 + + false + true + true + + ArrayList + GCEnergyProduction + String + + + + 1777995108221 + + 60 + 1790 + + false + true + true + + ArrayList + GCEnergyProduction + String + + + + 1777995108226 + + 60 + 1880 + + false + true + true + + ArrayList + GCGridBattery + String + + diff --git a/_alp/Agents/tabElectricity/Code/Functions.java b/_alp/Agents/tabElectricity/Code/Functions.java index 029fe10..6e3e56f 100644 --- a/_alp/Agents/tabElectricity/Code/Functions.java +++ b/_alp/Agents/tabElectricity/Code/Functions.java @@ -1,7 +1,6 @@ double f_setPVOnLand(double hectare,List gcListProduction) {/*ALCODESTART::1722256117103*/ -// TODO: Change to work for multiple solar fields in one model. -// to do so it should probably first calculate the total installed pv in all solar fields +// Single solarfarm at GridNode T0 for ( GCEnergyProduction GCEP : gcListProduction) { for(J_EAProduction j_ea : GCEP.c_productionAssets) { if (j_ea.getEAType() == OL_EnergyAssetType.PHOTOVOLTAIC) { @@ -90,9 +89,7 @@ double f_setWindTurbines(double AllocatedWindPower_MW,List gcListProduction) {/*ALCODESTART::1722256248965*/ -// TODO: Change to work for multiple wind farms in one model. -// to do so it should probably first calculate the total installed wind power in all wind farms - +// Single windfarm at GridNode T0 for ( GCEnergyProduction GCEP : gcListProduction) { for(J_EAProduction j_ea : GCEP.c_productionAssets) { if (j_ea.getEAType() == OL_EnergyAssetType.WINDMILL) { @@ -140,18 +137,18 @@ zero_Interface.f_resetSettings(); /*ALCODEEND*/} -double f_getCurrentPVOnLandAndWindturbineValues() +double f_getInitialPVOnLandAndWindturbineValues() {/*ALCODESTART::1745483988251*/ -p_currentPVOnLand_ha = 0; -p_currentWindTurbines_MW = 0; +p_initialPVOnLand_ha = 0; +p_initialWindTurbines_MW = 0; for(GCEnergyProduction GCProd : uI_Tabs.f_getAllSliderGridConnections_production()){ - if(!c_electricityTabEASliderGCs.contains(GCProd) && GCProd.v_isActive){ + if(!c_electricityTabEASliderGCs.contains(GCProd) && !zero_Interface.c_customSolarfarmGCs.contains(GCProd) && !zero_Interface.c_customWindfarmGCs.contains(GCProd) && GCProd.v_isActive){ for(J_EAProduction ea : GCProd.c_productionAssets){ if(ea.getEAType() == OL_EnergyAssetType.PHOTOVOLTAIC){ - p_currentPVOnLand_ha += ea.getCapacityElectric_kW()/zero_Interface.energyModel.avgc_data.p_avgSolarFieldPower_kWppha; + p_initialPVOnLand_ha += ea.getCapacityElectric_kW()/zero_Interface.energyModel.avgc_data.p_avgSolarFieldPower_kWppha; } else if(ea.getEAType() == OL_EnergyAssetType.WINDMILL){ - p_currentWindTurbines_MW += ea.getCapacityElectric_kW()/1000; + p_initialWindTurbines_MW += ea.getCapacityElectric_kW()/1000; } } } @@ -560,18 +557,18 @@ else if(page == gr_electricitySliders_collective){ {/*ALCODESTART::1756302457919*/ c_electricityTabEASliderGCs.addAll(electricityTabEASliderGCs); -f_getCurrentPVOnLandAndWindturbineValues(); -f_getCurrentGridBatterySize(); +f_getInitialPVOnLandAndWindturbineValues(); +f_getInitialGridBatterySize(); f_initializeElectricityPages(); /*ALCODEEND*/} -double f_getCurrentGridBatterySize() +double f_getInitialGridBatterySize() {/*ALCODESTART::1765276703854*/ -p_currentTotalGridBatteryCapacity_MWh = 0; +p_initialTotalGridBatteryCapacity_MWh = 0; for(GCGridBattery GCBat : uI_Tabs.f_getAllSliderGridConnections_gridBatteries()){ - if(!c_electricityTabEASliderGCs.contains(GCBat) && GCBat.v_isActive){ - p_currentTotalGridBatteryCapacity_MWh += (GCBat.p_batteryAsset.getStorageCapacity_kWh()/1000.0); + if(!c_electricityTabEASliderGCs.contains(GCBat) && !zero_Interface.c_customGridBatteryGCs.contains(GCBat) && GCBat.v_isActive){ + p_initialTotalGridBatteryCapacity_MWh += (GCBat.p_batteryAsset.getStorageCapacity_kWh()/1000.0); } } /*ALCODEEND*/} @@ -637,12 +634,12 @@ ShapeGroup f_updatePageIndicator() List productionGridConnections = new ArrayList<>(uI_Tabs.f_getAllSliderGridConnections_production()); //Large scale EA production systems (PV/Wind on land) -f_getCurrentPVOnLandAndWindturbineValues(); // Used for slider minimum: non adjustable GCProductions +f_getInitialPVOnLandAndWindturbineValues(); // Used for slider minimum: non adjustable GCProductions double totalPVOnLand_kW = 0; // Of movable slider GC double totalWind_kW = 0; // Of movable slider GC -for(GridConnection productionGC : c_electricityTabEASliderGCs){ +for(GridConnection productionGC : c_electricityTabEASliderGCs){ // Default slider solarfarm/windfarm collection if(productionGC instanceof GCEnergyProduction && productionGC.v_isActive){ for(J_EAProduction productionEA : productionGC.c_productionAssets){ if(productionEA.getEAType() == OL_EnergyAssetType.PHOTOVOLTAIC){ @@ -656,25 +653,61 @@ else if(productionEA.getEAType() == OL_EnergyAssetType.WINDMILL){ } } } -sl_largeScalePV_ha.setRange(0, 1000); // Needed to prevent anylogic range bug -sl_largeScalePV_ha.setValue((totalPVOnLand_kW/zero_Interface.energyModel.avgc_data.p_avgSolarFieldPower_kWppha) + p_currentPVOnLand_ha, false); -sl_largeScaleWind_MW.setRange(0, 1000); // Needed to prevent anylogic range bug -sl_largeScaleWind_MW.setValue((totalWind_kW/1000) + p_currentWindTurbines_MW, false); + +double totalCustomPVOnLand_kW = 0; +for(GCEnergyProduction customSF : zero_Interface.c_customSolarfarmGCs){ + if(customSF.v_isActive){ + for(J_EAProduction ea : customSF.c_productionAssets){ + if(ea.getEAType() == OL_EnergyAssetType.PHOTOVOLTAIC){ + totalCustomPVOnLand_kW += ea.getCapacityElectric_kW(); + } + } + } +} + +double totalCustomWind_kW = 0; +for(GCEnergyProduction customWF : zero_Interface.c_customWindfarmGCs){ + if(customWF.v_isActive){ + for(J_EAProduction ea : customWF.c_productionAssets){ + if(ea.getEAType() == OL_EnergyAssetType.WINDMILL){ + totalCustomWind_kW += ea.getCapacityElectric_kW(); + } + } + } +} + +double minSliderPVOnLand_ha = p_initialPVOnLand_ha + totalCustomPVOnLand_kW/zero_Interface.energyModel.avgc_data.p_avgSolarFieldPower_kWppha; +double maxSliderPVOnLand_ha = minSliderPVOnLand_ha + 50; +sl_largeScalePV_ha.setRange(minSliderPVOnLand_ha, maxSliderPVOnLand_ha); +sl_largeScalePV_ha.setValue((totalPVOnLand_kW/zero_Interface.energyModel.avgc_data.p_avgSolarFieldPower_kWppha) + minSliderPVOnLand_ha, false); + +double minSliderWind_MW = p_initialWindTurbines_MW + totalCustomWind_kW/1000; +double maxSliderWind_MW = minSliderWind_MW + 100; +sl_largeScaleWind_MW.setRange(minSliderWind_MW, maxSliderWind_MW); +sl_largeScaleWind_MW.setValue((totalWind_kW/1000) + minSliderWind_MW, false); //Grid batteries -List sliderGridBatteryGridConnections = new ArrayList<>(); -for(GridConnection sliderGC : c_electricityTabEASliderGCs){ +f_getInitialGridBatterySize(); // Used for slider minimum: non adjustable GCGridBatteries + +double totalDefaultBatteryCapacity_kWh = 0; +for(GridConnection sliderGC : c_electricityTabEASliderGCs){ // Default slider battery collection if(sliderGC.v_isActive && sliderGC instanceof GCGridBattery sliderGridBattery){ - sliderGridBatteryGridConnections.add(sliderGridBattery); + totalDefaultBatteryCapacity_kWh += sliderGridBattery.p_batteryAsset.getStorageCapacity_kWh(); } } -double averageNeighbourhoodBatterySize_kWh = 0; -for (GCGridBattery gc : sliderGridBatteryGridConnections) { - averageNeighbourhoodBatterySize_kWh += gc.p_batteryAsset.getStorageCapacity_kWh()/sliderGridBatteryGridConnections.size(); +double totalCustomBatteryCapacity_kWh = 0; +for(GridConnection customGB : zero_Interface.c_customGridBatteryGCs){ + if(customGB.v_isActive && customGB.p_batteryAsset != null){ + totalCustomBatteryCapacity_kWh += customGB.p_batteryAsset.getStorageCapacity_kWh(); + } } -sl_gridBatteries_kWh.setValue(averageNeighbourhoodBatterySize_kWh, false); + +double minSliderGridBattery_kWh = p_initialTotalGridBatteryCapacity_MWh*1000 + totalCustomBatteryCapacity_kWh; +double maxSliderGridBattery_kWh = minSliderGridBattery_kWh + 20000; +sl_gridBatteries_kWh.setRange(minSliderGridBattery_kWh, maxSliderGridBattery_kWh); +sl_gridBatteries_kWh.setValue(totalDefaultBatteryCapacity_kWh + minSliderGridBattery_kWh, false); //Curtailment large scale PV and wind boolean curtailment = true; diff --git a/_alp/Agents/tabElectricity/Code/Functions.xml b/_alp/Agents/tabElectricity/Code/Functions.xml index 50ab0e9..bee1648 100644 --- a/_alp/Agents/tabElectricity/Code/Functions.xml +++ b/_alp/Agents/tabElectricity/Code/Functions.xml @@ -105,7 +105,7 @@ VOID double 1745483988251 - + 30 1250