diff --git a/data/examples/cost_params.json b/data/examples/cost_params.json index 38359dff..172fa1c6 100644 --- a/data/examples/cost_params.json +++ b/data/examples/cost_params.json @@ -25,51 +25,6 @@ "lifetime_battery": 7, "cost_per_kWh": 250 }, - "gc": { - "LV": { - "default_distance": 50, - "capex_gc_fix": 100, - "capex_gc_per_meter": 16.85, - "capex_gc_per_kW": 24.14, - "capex_transformer_fix": 0, - "capex_transformer_per_kW": 0 - }, - "MV/LV": { - "default_distance": 100, - "capex_gc_fix": 100, - "capex_gc_per_meter": 16.85, - "capex_gc_per_kW": 24.14, - "capex_transformer_fix": 0, - "capex_transformer_per_kW": 0 - }, - "MV": { - "default_distance": 200, - "capex_gc_fix": 62500, - "capex_gc_per_meter": 562.5, - "capex_gc_per_kW": 158.3, - "capex_transformer_fix": 80000, - "capex_transformer_per_kW": 0 - }, - "HV/MV": { - "default_distance": 2000, - "capex_gc_fix": 0, - "capex_gc_per_meter": 80, - "capex_gc_per_kW": 158.3, - "capex_transformer_fix": 0, - "capex_transformer_per_kW": 63.49 - }, - "HV": { - "default_distance": 2000, - "capex_gc_fix": 0, - "capex_gc_per_meter": 1300, - "capex_gc_per_kW": 158.3, - "capex_transformer_fix": 2500000, - "capex_transformer_per_kW": 0 - }, - "lifetime_gc": 50, - "c_maint_transformer_per_year": 0.02, - "lifetime_transformer": 20 - }, "stationary_storage": { "capex_fix": 1, "capex_per_kWh": 1, @@ -89,108 +44,173 @@ "cost_per_workstation": 245000, "lifetime_workstations": 20 }, - "grid_fee":{ - "SLP": { - "basic_charge_EUR/a": { - "net_price": 65.7, - "gross_price": 78.18, - "unit": "EUR/a", - "info": "basic charge for SLP (standard load profile) customers." + "default_grid_operator": { + "gc": { + "LV": { + "default_distance": 50, + "capex_gc_fix": 100, + "capex_gc_per_meter": 16.85, + "capex_gc_per_kW": 24.14, + "capex_transformer_fix": 0, + "capex_transformer_per_kW": 0 }, - "commodity_charge_ct/kWh": { - "net_price": 7.48, - "gross_price": 8.9, - "unit": "ct/kWh", - "info": "commodity costs for SLP (standard load profile) customers" - } + "MV/LV": { + "default_distance": 100, + "capex_gc_fix": 100, + "capex_gc_per_meter": 16.85, + "capex_gc_per_kW": 24.14, + "capex_transformer_fix": 0, + "capex_transformer_per_kW": 0 + }, + "MV": { + "default_distance": 200, + "capex_gc_fix": 62500, + "capex_gc_per_meter": 562.5, + "capex_gc_per_kW": 158.3, + "capex_transformer_fix": 80000, + "capex_transformer_per_kW": 0 + }, + "HV/MV": { + "default_distance": 2000, + "capex_gc_fix": 0, + "capex_gc_per_meter": 80, + "capex_gc_per_kW": 158.3, + "capex_transformer_fix": 0, + "capex_transformer_per_kW": 63.49 + }, + "HV": { + "default_distance": 2000, + "capex_gc_fix": 0, + "capex_gc_per_meter": 1300, + "capex_gc_per_kW": 158.3, + "capex_transformer_fix": 2500000, + "capex_transformer_per_kW": 0 + }, + "lifetime_gc": 50, + "c_maint_transformer_per_year": 0.02, + "lifetime_transformer": 20 }, - "RLM": { - "<2500_h/a": { - "capacity_charge_EUR/kW*a": { - "HV": 19.13, - "HV/MV": 25.25, - "MV": 41.06, - "MV/LV": 44.26, - "LV": 44.26, - "unit": "EUR/(kW*a)", - "info": ["capacity charge depending on the voltage level for RLM", - "(Registrierende Leistungsmessung, engl.: consumption metering) customers with", - "annual utilization time < 2500 h/a"] + "grid_fee": { + "SLP": { + "basic_charge_EUR/a": { + "net_price": 65.7, + "gross_price": 78.18, + "unit": "EUR/a", + "info": "basic charge for SLP (standard load profile) customers." }, "commodity_charge_ct/kWh": { - "HV": 2.3, - "HV/MV": 3.81, - "MV": 3.49, - "MV/LV": 4.39, - "LV": 4.83, + "net_price": 7.48, + "gross_price": 8.9, "unit": "ct/kWh", - "info": ["commodity charge depending on the voltage level for RLM", - "(Registrierende Leistungsmessung, engl.: consumption metering) customers with", - "annual utilization time < 2500 h/a"] + "info": "commodity costs for SLP (standard load profile) customers" } }, - ">=2500_h/a": { - "capacity_charge_EUR/kW*a": { - "HV": 56.33, - "HV/MV": 101.52, - "MV": 70.14, - "MV/LV": 97.01, - "LV": 64.33, - "unit": "EUR/(kW*a)", - "info": ["capacity charge depending on the voltage level for RLM customers with", - "annual utilization time >= 2500 h/a"] + "RLM": { + "<2500_h/a": { + "capacity_charge_EUR/kW*a": { + "HV": 19.13, + "HV/MV": 25.25, + "MV": 41.06, + "MV/LV": 44.26, + "LV": 44.26, + "unit": "EUR/(kW*a)", + "info": [ + "capacity charge depending on the voltage level for RLM", + "(Registrierende Leistungsmessung, engl.: consumption metering) customers with", + "annual utilization time < 2500 h/a" + ] + }, + "commodity_charge_ct/kWh": { + "HV": 2.3, + "HV/MV": 3.81, + "MV": 3.49, + "MV/LV": 4.39, + "LV": 4.83, + "unit": "ct/kWh", + "info": [ + "commodity charge depending on the voltage level for RLM", + "(Registrierende Leistungsmessung, engl.: consumption metering) customers with", + "annual utilization time < 2500 h/a" + ] + } }, - "commodity_charge_ct/kWh": { - "HV": 0.81, - "HV/MV": 0.76, - "MV": 2.32, - "MV/LV": 2.28, - "LV": 4.03, - "unit": "ct/kWh", - "info": ["commodity charge depending on the voltage level for RLM customers with", - "annual utilization time >= 2500 h/a"] + ">=2500_h/a": { + "capacity_charge_EUR/kW*a": { + "HV": 56.33, + "HV/MV": 101.52, + "MV": 70.14, + "MV/LV": 97.01, + "LV": 64.33, + "unit": "EUR/(kW*a)", + "info": [ + "capacity charge depending on the voltage level for RLM customers with", + "annual utilization time >= 2500 h/a" + ] + }, + "commodity_charge_ct/kWh": { + "HV": 0.81, + "HV/MV": 0.76, + "MV": 2.32, + "MV/LV": 2.28, + "LV": 4.03, + "unit": "ct/kWh", + "info": [ + "commodity charge depending on the voltage level for RLM customers with", + "annual utilization time >= 2500 h/a" + ] + } + }, + "additional_costs": { + "costs": 0, + "unit": "EUR", + "info": "additional costs for RLM customers per year (f.i. costs for metering point operation)" } - }, - "additional_costs": { - "costs": 0, - "unit": "EUR", - "info": "additional costs for RLM customers per year (f.i. costs for metering point operation)" } - } - }, - "power_procurement": { - "charge": 7.7, - "unit": "ct/kWh", - "info": "charge for power generation, power procurement and sales" - }, - "levies": { - "EEG-levy": 0, - "chp_levy": 0.378, - "individual_charge_levy": 0.437, - "offshore_levy": 0.419, - "interruptible_loads_levy": 0.003, - "unit": "ct/kWh", - "info": ["levies on energy supplied from the power grid"] - }, - "concession_fee": { - "charge": 1.32, - "unit": "ct/kWh", - "info": "concession fee depending on the tariff and the size of the municipality" - }, - "taxes": { - "value_added_tax": 19, - "tax_on_electricity": 2.05, - "unit": "value added tax: %, tax on electricity: ct/kWh", - "info": "taxes on energy supplied from the power grid" - }, - "feed-in_remuneration": { - "PV": { - "kWp": [10, 40, 100], - "remuneration": [6.24, 6.06, 4.74] }, - "V2G": 0, - "battery": 0, - "unit": "ct/kWh", - "info": "remuneration for power fed into the grid by PV power plants or electric vehicles" + "power_procurement": { + "charge": 7.7, + "unit": "ct/kWh", + "info": "charge for power generation, power procurement and sales" + }, + "levies": { + "EEG_levy": 0, + "chp_levy": 0.378, + "individual_charge_levy": 0.437, + "offshore_levy": 0.419, + "interruptible_loads_levy": 0.003, + "unit": "ct/kWh", + "info": [ + "levies on energy supplied from the power grid" + ] + }, + "concession_fee": { + "charge": 1.32, + "unit": "ct/kWh", + "info": "concession fee depending on the tariff and the size of the municipality" + }, + "taxes": { + "value_added_tax": 19, + "tax_on_electricity": 2.05, + "unit": "value added tax: %, tax on electricity: ct/kWh", + "info": "taxes on energy supplied from the power grid" + }, + "feed-in_remuneration": { + "PV": { + "kWp": [ + 10, + 40, + 100 + ], + "remuneration": [ + 6.24, + 6.06, + 4.74 + ] + }, + "V2G": 0, + "battery": 0, + "unit": "ct/kWh", + "info": "remuneration for power fed into the grid by PV power plants or electric vehicles" + } } } diff --git a/data/examples/electrified_stations.json b/data/examples/electrified_stations.json index 40d4ffa9..e77019f3 100644 --- a/data/examples/electrified_stations.json +++ b/data/examples/electrified_stations.json @@ -6,6 +6,7 @@ "gc_power": 5000, // optional: maximum gc power for this station, default defined in config "cs_power_deps_oppb" : 50, // optional: maximum cs power for this station, default defined in config "cs_power_deps_depb" : 120, // optional: maximum cs power for this station, default defined in config + "grid_operator" : "default_grid_operator", // optional: set grid operator for cost calculation. Default is "default_grid_operator" "voltage_level": "MV", // optional: voltage_level for this station, default defined in config "energy_feed_in": { // optional: energy feed in e.g. by local renewables "csv_file": "data/examples/example_pv_feedin.csv", // path to feedin.csv diff --git a/docs/source/simba_features.rst b/docs/source/simba_features.rst index 45e58995..b06d69e5 100644 --- a/docs/source/simba_features.rst +++ b/docs/source/simba_features.rst @@ -76,6 +76,7 @@ Cost calculation ################ | **Cost calculation (summary_vehicles_costs.csv)** | This is an optional output which calculates investment and maintenance costs of the infrastructure as well as energy costs in the scenario. The costs are calculated based on the price sheet, given as input in the :ref:`cost_params`. +| The energy costs and the grid connector costs are spefific for each grid operator, as given by the :ref:`cost_params`. | The following costs are calculated as both total and annual, depending on the lifetime of each component. See `SpiceEV documentation `_ for the calculation of electricity costs. * Investment diff --git a/docs/source/simulation_parameters.rst b/docs/source/simulation_parameters.rst index aa349694..fe686227 100644 --- a/docs/source/simulation_parameters.rst +++ b/docs/source/simulation_parameters.rst @@ -289,19 +289,6 @@ In order to run the :ref:`cost_calculation`, all cost parameters are to be defin "lifetime_battery": 7, // lifetime of the vehicle battery in years "cost_per_kWh": 250 // investment cost for vehicle battery per kWh }, - "gc": { // grid connection - "LV": { // grid connection in specific voltage level. Options are "HV", "HV/MV", "MV", "MV/LV", "LV" and all relevant voltage levels have to be defined here - "default_distance": 50, // Used if not specified individually in electrified_stations.json - "capex_gc_fix": 100, // fix investment cost for establishing a grid connection - "capex_gc_per_meter": 16.85, // investment cost per meter - "capex_gc_per_kW": 24.14, // investment cost per kW - "capex_transformer_fix": 0, // fix investment cost for a transformer - "capex_transformer_per_kW": 0 // fix investment cost for a transformer per kW - }, - "lifetime_gc": 50, // lifetime of the grid connection in years - "c_maint_transformer_per_year": 0.02, // annual maintenance costs in % of capex - "lifetime_transformer": 20 // lifetime in years - }, "stationary_storage": { // stationary electric energy storage "capex_fix": 1, // fix investment cost for stationary storage "capex_per_kWh": 1, // investment cost for stationary storage per kWh @@ -320,10 +307,25 @@ In order to run the :ref:`cost_calculation`, all cost parameters are to be defin "vehicles_per_workstation": 20, // how many vehicles share one workstation "cost_per_workstation": 245000, // investment cost for one workstation "lifetime_workstations": 20 // lifetime in years + }, + "grid operator": { + "gc": { // grid connection + "LV": { // grid connection in specific voltage level. Options are "HV", "HV/MV", "MV", "MV/LV", "LV" and all relevant voltage levels have to be defined here + "default_distance": 50, // Used if not specified individually in electrified_stations.json + "capex_gc_fix": 100, // fix investment cost for establishing a grid connection + "capex_gc_per_meter": 16.85, // investment cost per meter + "capex_gc_per_kW": 24.14, // investment cost per kW + "capex_transformer_fix": 0, // fix investment cost for a transformer + "capex_transformer_per_kW": 0 // fix investment cost for a transformer per kW + }, + "lifetime_gc": 50, // lifetime of the grid connection in years + "c_maint_transformer_per_year": 0.02, // annual maintenance costs in % of capex + "lifetime_transformer": 20 // lifetime in years + } } } -all remaining parameters are described in the example file. +All remaining parameters such as grid fees or energy taxes are described in the example file. .. _station_geo_data: diff --git a/simba/costs.py b/simba/costs.py index 38f55726..35049bac 100644 --- a/simba/costs.py +++ b/simba/costs.py @@ -7,7 +7,7 @@ def calculate_costs(c_params, scenario, schedule, args): """ Calculates annual costs of all necessary vehicles and infrastructure. - :param c_params: Cost of various infrastructure components. + :param c_params: Infrastructure component costs and specific grid operator costs. :type c_params: dict :param scenario: Information about the simulated scenario and all used parameters. :type scenario: Scenario @@ -15,6 +15,7 @@ def calculate_costs(c_params, scenario, schedule, args): :type schedule: Schedule :param args: Configuration arguments specified in config files contained in configs directory. :type args: argparse.Namespace + :raises Exception: if grid operator of grid connector can not be found in cost params """ # initialize dictionary with all costs @@ -56,8 +57,14 @@ def calculate_costs(c_params, scenario, schedule, args): costs["c_vehicles_annual"] += c_vehicles_vt / c_params["vehicles"][v_type]["lifetime"] # GRID CONNECTION POINTS - gc_in_use = schedule.scenario["components"]["grid_connectors"] - for gcID in gc_in_use.keys(): + gc_in_use = scenario.components.grid_connectors + for gcID, gc in gc_in_use.items(): + # get dict with costs for specific grid operator + try: + c_params_go = c_params[gc.grid_operator] + except KeyError: + raise Exception(f"{gcID}: Unknown grid operator {gc.grid_operator}, " + "might have to set in electrified stations or cost params") # get max. power of grid connector gc_timeseries = getattr(scenario, f"{gcID}_timeseries") gc_max_power = -min(gc_timeseries["grid supply [kW]"]) @@ -65,23 +72,23 @@ def calculate_costs(c_params, scenario, schedule, args): voltage_level = schedule.stations[gcID].get("voltage_level", args.default_voltage_level) # get distance between grid and grid connector distance_to_grid = schedule.stations[gcID].get( - "distance_to_grid", c_params["gc"][voltage_level]["default_distance"]) + "distance_to_grid", c_params_go["gc"][voltage_level]["default_distance"]) # calculate grid connection costs, typically building costs and building cost subsidy - c_gc = (c_params["gc"][voltage_level]["capex_gc_fix"] + - c_params["gc"][voltage_level]["capex_gc_per_kW"] * gc_max_power + - c_params["gc"][voltage_level]["capex_gc_per_meter"] * distance_to_grid) + c_gc = (c_params_go["gc"][voltage_level]["capex_gc_fix"] + + c_params_go["gc"][voltage_level]["capex_gc_per_kW"] * gc_max_power + + c_params_go["gc"][voltage_level]["capex_gc_per_meter"] * distance_to_grid) # calculate transformer costs c_transformer = ( - c_params["gc"][voltage_level]["capex_transformer_fix"] + - c_params["gc"][voltage_level]["capex_transformer_per_kW"] * gc_max_power) + c_params_go["gc"][voltage_level]["capex_transformer_fix"] + + c_params_go["gc"][voltage_level]["capex_transformer_per_kW"] * gc_max_power) # calculate total cost of grid connection costs["c_gcs"] += c_gc + c_transformer # calculate annual costs of grid connection, depending on lifetime of gc and transformer - costs["c_gcs_annual"] += (c_gc / c_params["gc"]["lifetime_gc"] + - c_transformer / c_params["gc"]["lifetime_transformer"]) + costs["c_gcs_annual"] += (c_gc / c_params_go["gc"]["lifetime_gc"] + + c_transformer / c_params_go["gc"]["lifetime_transformer"]) # calculate maintenance cost of grid connection costs["c_maint_gc_annual"] += ( - c_transformer * c_params["gc"]["c_maint_transformer_per_year"]) + c_transformer * c_params_go["gc"]["c_maint_transformer_per_year"]) # STATIONARY STORAGE # assume there is a stationary storage @@ -200,7 +207,8 @@ def calculate_costs(c_params, scenario, schedule, args): power_v2g_feed_in_list=timeseries.get("V2G feed-in [kW]"), power_battery_feed_in_list=timeseries.get("battery feed-in [kW]"), charging_signal_list=timeseries.get("window"), - price_sheet_json=args.cost_parameters_file, + price_sheet_path=args.cost_parameters_file, + grid_operator=gc.grid_operator, power_pv_nominal=pv, ) diff --git a/simba/schedule.py b/simba/schedule.py index fbc7e458..2bf6f3ec 100644 --- a/simba/schedule.py +++ b/simba/schedule.py @@ -551,6 +551,7 @@ def generate_scenario(self, args): "max_power": gc_power, "cost": {"type": "fixed", "value": 0.3}, "number_cs": station["n_charging_stations"], + "grid_operator": station.get("grid_operator", "default_grid_operator"), "voltage_level": station.get("voltage_level", args.default_voltage_level) }