Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility patch for SpiceEV PR #217 #214

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions data/examples/simba.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ strategy_opps = greedy
strategy_options_deps = {"CONCURRENCY": 1}
strategy_options_opps = {}

# Cost calculation strategy
cost_calculation_strategy_deps = balanced
cost_calculation_strategy_opps = greedy
# Cost calculation to use. Remove to use default for strategy.
stefansc1 marked this conversation as resolved.
Show resolved Hide resolved
cost_calculation_method_deps = fixed_wo_plw
cost_calculation_method_opps = fixed_wo_plw

##### Physical setup of environment #####
### Parametrization of the physical setup ###
Expand Down
16 changes: 8 additions & 8 deletions docs/source/simulation_parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ The example (data/simba.cfg) contains parameter descriptions which are explained
- greedy
- SpiceEV Strategies (greedy, balanced, peak_shaving, peak_load_windows, balanced_market)
- Charging strategy used in opportunity stations.
* - cost_calculation_strategy_deps
- strategy_deps value
- SpiceEV Strategies (greedy, balanced, peak_shaving, peak_load_windows, balanced_market)
- Strategy for cost calculation at depots.
* - cost_calculation_strategy_opps
- strategy_opps value
- SpiceEV Strategies (greedy, balanced, peak_shaving, peak_load_windows, balanced_market)
- Strategy for cost calculation at opportunity stations.
* - cost_calculation_method_deps
- fixed_wo_plw
- SpiceEV cost calculation type
stefansc1 marked this conversation as resolved.
Show resolved Hide resolved
- Method for cost calculation at depots.
* - cost_calculation_method_opps
- fixed_wo_plw
- SpiceEV cost calculation type (fixed_wo_plw, fixed_w_plw, balanced_market, flex_window)
- Method for cost calculation at opportunity stations.
* - preferred_charging_type
- depb
- depb, oppb
Expand Down
36 changes: 20 additions & 16 deletions simba/costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import traceback
import warnings

import spice_ev.scenario
from spice_ev.costs import calculate_costs as calc_costs_spice_ev

import simba.schedule

import spice_ev.costs
import spice_ev.scenario
import spice_ev.util


def calculate_costs(c_params, scenario, schedule, args):
""" Calculates annual costs of all necessary vehicles and infrastructure.
Expand Down Expand Up @@ -320,21 +321,23 @@ def set_electricity_costs(self):
if pv.parent == gcID])
timeseries = vars(self.scenario).get(f"{gcID}_timeseries")

# Get the calculation strategy / method from args.
# If no value is set, use the same strategy as the charging strategy
default_cost_strategy = vars(self.args)["strategy_" + station.get("type")]

cost_strategy_name = "cost_calculation_strategy_" + station.get("type")
cost_calculation_strategy = (vars(self.args).get(cost_strategy_name)
or default_cost_strategy)
# Get the calculation method from args.
cost_calculation_name = "cost_calculation_method_" + station.get("type")
cost_calculation_method = vars(self.args).get(cost_calculation_name)
if cost_calculation_method is None:
# not given in config: use the same method as the charging strategy
default_strategy = vars(self.args)["strategy_" + station.get("type")]
cost_calculation_method = spice_ev.costs.DEFAULT_COST_CALCULATION[default_strategy]

# calculate costs for electricity
try:
if cost_calculation_strategy == "peak_load_window":
if timeseries.get("window signal [-]") is None:
raise Exception("No peak load window signal provided for cost calculation")
costs_electricity = calc_costs_spice_ev(
strategy=cost_calculation_strategy,
is_peak_load_window = cost_calculation_method.endswith("w_plw")
if is_peak_load_window and timeseries.get("window signal [-]") is None:
logging.info("Generating peak load window signal for cost calculation")
timeseries["window signal [-]"] = spice_ev.util.get_time_windows_from_json(
self.args.time_windows, gc.grid_operator, gc.voltage_level, self.scenario)
costs_electricity = spice_ev.costs.calculate_costs(
cc_type=cost_calculation_method,
voltage_level=gc.voltage_level,
interval=self.scenario.interval,
timestamps_list=timeseries.get("time"),
Expand All @@ -344,9 +347,10 @@ def set_electricity_costs(self):
power_generation_feed_in_list=timeseries.get("generation feed-in [kW]"),
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 signal [-]"),
window_signal_list=timeseries.get("window signal [-]"),
price_sheet_path=self.args.cost_parameters_path,
grid_operator=gc.grid_operator,
fee_type=None, # "RLM" or "SLP" or None (based on energy consumption)
power_pv_nominal=pv,
)
except Exception:
Expand Down
11 changes: 6 additions & 5 deletions simba/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import subprocess
from datetime import datetime, timedelta

from spice_ev.costs import COST_CALCULATION
from spice_ev.strategy import STRATEGIES
from spice_ev.util import set_options_from_config

Expand Down Expand Up @@ -531,11 +532,11 @@ def get_parser():
parser.add_argument('--strategy-opps', default='greedy', choices=STRATEGIES,
help='strategy to use at station')

# #### Cost calculation strategy #####
parser.add_argument('--cost-calculation-strategy-deps', choices=STRATEGIES,
help='Strategy for cost calculation to use in depot')
parser.add_argument('--cost-calculation-strategy-opps', choices=STRATEGIES,
help='Strategy for cost calculation to use at station')
# #### Cost calculation method #####
parser.add_argument('--cost-calculation-method-deps', choices=COST_CALCULATION,
help='Cost calculation to use in depot')
parser.add_argument('--cost-calculation-method-opps', choices=COST_CALCULATION,
help='Cost calculation to use at station')

parser.add_argument('--strategy-options-deps', default={},
type=lambda s: s if type(s) is dict else json.loads(s),
Expand Down
31 changes: 13 additions & 18 deletions tests/test_cost_calculation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ def test_cost_calculation(self):
assert args.strategy_deps == "balanced"
assert args.strategy_opps == "greedy"

args.cost_calculation_strategy_deps = None
args.cost_calculation_strategy_opps = None
args.cost_calculation_method_deps = None
args.cost_calculation_method_opps = None

costs_vanilla = calculate_costs(cost_params, scenario, schedule, args)

assert args.strategy_deps == "balanced"
assert args.strategy_opps == "greedy"

args.cost_calculation_strategy_deps = "balanced"
args.cost_calculation_strategy_opps = "greedy"
args.cost_calculation_method_deps = "fixed_wo_plw"
args.cost_calculation_method_opps = "fixed_wo_plw"
costs_with_same_strat = calculate_costs(cost_params, scenario, schedule, args)

# assert all costs are the same
Expand All @@ -31,8 +31,9 @@ def test_cost_calculation(self):
assert (costs_vanilla.costs_per_gc[station][key] ==
costs_with_same_strat.costs_per_gc[station][key]), station

args.cost_calculation_strategy_opps = "balanced_market"
args.cost_calculation_strategy_deps = "balanced_market"
# test with different method (balanced_market costs for balanced strategy)
args.cost_calculation_method_deps = "balanced_market"
args.cost_calculation_method_opps = "balanced_market"
costs_with_other_strat = calculate_costs(cost_params, scenario, schedule, args)
print(costs_vanilla.costs_per_gc["cumulated"]["c_total_annual"])
print(costs_with_other_strat.costs_per_gc["cumulated"]["c_total_annual"])
Expand All @@ -43,21 +44,15 @@ def test_cost_calculation(self):
assert (costs_vanilla.costs_per_gc[station][key] !=
costs_with_other_strat.costs_per_gc[station][key]), key

args.cost_calculation_strategy_opps = "peak_load_window"
args.cost_calculation_strategy_deps = "peak_load_window"
# PLW: will create window time series before cost calculation
args.cost_calculation_method_deps = "fixed_w_plw"
args.cost_calculation_method_opps = "fixed_w_plw"
costs_with_other_strat = calculate_costs(cost_params, scenario, schedule, args)
"""
station = "cumulated"
for key in costs_vanilla.costs_per_gc[station]:
if "el_energy" not in key:
continue
assert (costs_vanilla.costs_per_gc[station][key] !=
costs_with_other_strat.costs_per_gc[station][key]), key

args.cost_calculation_strategy_opps = "peak_shaving"
args.cost_calculation_strategy_deps = "peak_shaving"
costs_with_other_strat = calculate_costs(cost_params, scenario, schedule, args)
# assert all costs are the same
for station in costs_vanilla.costs_per_gc:
for key in costs_vanilla.costs_per_gc[station]:
assert (costs_vanilla.costs_per_gc[station][key] ==
costs_with_other_strat.costs_per_gc[station][key]), station
costs_with_other_strat.costs_per_gc[station][key]), key
"""
Loading