sustaingym.envs.evcharging.env#

The module implements the EVChargingEnv class.

Module Contents#

Classes#

EVChargingEnv

EVCharging class.

Functions#

magnitude_constraint(→ cvxpy.Constraint)

Creates constraint requiring that aggregate magnitude (A) must be less

class sustaingym.envs.evcharging.env.EVChargingEnv(data_generator: sustaingym.envs.evcharging.event_generation.AbstractTraceGenerator, moer_forecast_steps: int = 36, project_action_in_env: bool = True, verbose: int = 0)[source]#

Bases: gymnasium.Env

EVCharging class.

This classes simulates the charging schedule of electric vehicles (or EVs) connected to an EV charging network. It is based on ACN-Data and ACN-Sim developed at Caltech. Each episode is a 24-hour day of charging, and the simulation can be done using real data from ACN-Data or a Gaussian mixture model (GMM) fitted on the data (see train_gmm_model.py). The gym supports the Caltech and JPL sites.

This environment’s API is known to be compatible with Gymnasium v0.28, v0.29.

In what follows:

  • n = number of stations in the EV charging network

  • k = number of steps for the MOER CO2 forecast

Actions:

Type: Box(n)
Action                              Shape   Min     Max
normalized pilot signal             n       0       1

Observations:

Type: Dict(Box(1), Box(n), Box(n), Box(1), Box(k))
                                    Shape   Min     Max
Timestep (fraction of day)          1       0       1
Estimated departures (timesteps)    n       -288    288
Demands (kWh)                       n       0       Max Allowed Energy Request
Previous MOER value                 1       0       1
Forecasted MOER (kg CO2 / kWh)      k       0       1
Parameters:
  • data_generator (sustaingym.envs.evcharging.event_generation.AbstractTraceGenerator) – generator for sampling EV charging events and MOER forecasts

  • moer_forecast_steps (int) – number of steps of MOER forecast to include, minimum of 1 and maximum of 36. Each step is 5 mins, for a maximum of 3 hrs.

  • project_action_in_env (bool) – whether gym should project action to obey network constraints and not overcharge vehicles

  • verbose (int) –

    level of verbosity for print out

    • 0: nothing

    • 1: print description of current simulation day

    • 2: print warnings from network constraint violations and convex optimization solver

# attributes required by gym.Env
action_space#

spaces.Box, structure of actions expected by env

observation_space#

spaces.Dict, structure of observations

reward_range#

tuple[float, float], min and max rewards

spec#

EnvSpec, info about env if initialized from gymnasium.make()

metadata#

dict[str, Any], unused

np_random#

np.random.Generator, random number generator for the env

# attributes specific to EVChargingEnv
data_generator#

AbstractTraceGenerator, generator for sampling EV charging events and MOER forecasting

max_timestep#

int, maximum timestep in a day’s simulation

moer_forecast_steps#

int, number of steps of MOER forecast to include

project_action_in_env#

bool, whether gym should project action to obey network constraints and not overcharge vehicles

verbose#

int, level of verbosity for print out

  • 0: nothing

  • 1: print description of current simulation day

  • 2: print warnings from network constraint violations and convex optimization solver

cn#

acns.ChargingNetwork, EV charging network

num_stations#

int, number of stations in EV charging network

timestep#

int, current timestep in episode, from 0 to 288

TIMESTEP_DURATION = 5[source]#
ACTION_SCALE_FACTOR = 32[source]#
VOLTAGE = 208[source]#
MARGINAL_REVENUE_PER_KWH = 0.15[source]#
OPERATING_MARGIN = 0.2[source]#
MARGINAL_PROFIT_PER_KWH[source]#
CO2_COST_PER_METRIC_TON = 30.85[source]#
A_MINS_TO_KWH[source]#
VIOLATION_WEIGHT = 0.001[source]#
A_PERS_TO_KWH[source]#
PROFIT_FACTOR[source]#
VIOLATION_FACTOR[source]#
CARBON_COST_FACTOR[source]#
step(action: numpy.ndarray) tuple[dict[str, numpy.ndarray], float, bool, bool, dict[str, Any]][source]#

Steps the environment.

Calls the step function of the internal simulator.

Parameters:

action (numpy.ndarray) – shape [num_stations], normalized charging rate for each charging station between 0 and 1.

Returns:
  • observation – state

    • ‘est_departures’: shape [num_stations], the estimated number of periods until departure. If there is no EVSE at the index, the entry is set to zero.

    • ‘demands’: shape [num_stations], amount of charge demanded by each EVSE in kWh.

    • ‘prev_moer’: shape [1], emissions rate for the current timestep in kg CO2 per kWh. Between 0 and 1.

    • ‘forecasted_moer’: shape [moer_forecast_steps], forecasted emissions rate for next timestep(s) in kg CO2 per kWh. Between 0 and 1.

    • ‘timestep’: shape [1], fraction of day between 0 and 1.

  • reward – scheduler’s performance metric per timestep

  • terminated – whether episode is terminated

  • truncated – always False, since there is no intermediate stopping condition

  • info – auxiliary useful information

    • ‘num_evs’: int, number of charging sessions in episode.

    • ‘avg_plugin_time’: float, average plugin time in periods (5 mins) across sessions in episode.

    • ‘max_profit’: float, maximum profit if all EVs were charged maximally while they are connected to the network. This does not take into account network constraints or carbon emissions, and it is a good proxy for info[‘reward_breakdown’][‘profit’].

    • ‘reward_breakdown’: dict[str, float], breakdown of evaluation metrics cumulative over the episode.

      • ‘profit’ ($) : profit over charge delivered to all EVs.

      • ‘carbon_cost’($): cost of marginal emissions.

      • ‘excess_charge’ ($): cost of network violations.

    • ‘evs’: list[acnm.ev.EV], list of EVs in the event queue

    • ‘active_evs’: list[acnm.ev.EV], list of active EVs at current timestep

    • ‘moer’: array, shape [289, 37] emissions rate for entire episode.

    • ‘pilot_signals’: DataFrame, pilot signals received by simulator

Return type:

tuple[dict[str, numpy.ndarray], float, bool, bool, dict[str, Any]]

reset(*, seed: int | None = None, options: dict[str, Any] | None = None) tuple[dict[str, numpy.ndarray], dict[str, Any]][source]#

Resets the environment.

Prepares for the next episode by re-creating the charging network, generating new events, creating the simulation and interface, and resetting information-tracking variables.

Parameters:
  • seed (int | None) – seed for resetting the environment. An episode is entirely reproducible no matter the generator used.

  • options (dict[str, Any] | None) –

    resetting options

    • ’verbose’: set verbosity level [0-2]

Returns:
  • observation – state dict, see step()

  • info – info dict, see step()

Return type:

tuple[dict[str, numpy.ndarray], dict[str, Any]]

close() None[source]#

Close the environment. Delete internal variables.

Return type:

None

sustaingym.envs.evcharging.env.magnitude_constraint(action: cvxpy.Variable, cn: acnportal.acnsim.ChargingNetwork) cvxpy.Constraint[source]#

Creates constraint requiring that aggregate magnitude (A) must be less than observation magnitude (A).

Parameters:
  • action (cvxpy.Variable) – shape [num_stations] or [num_stations, T], charging rates normalized to [0, 1]

  • cn (acnportal.acnsim.ChargingNetwork) –

Returns:

constr – constraint on aggregate magnitude

Return type:

cvxpy.Constraint