Skip to content

Resources

powerzoo.envs.resource.base.ResourceEnv(parent=None, bus_id=-1, delta_t_minutes=15.0, phase='ABC')

Bases: BaseEnv

Physical sub-resource base class (dynamics only, no CMDP).

A resource is responsible for one thing: given an action, update its internal physical state (SOC, power, temperature, etc.).

Resources are not standalone RL environments. They do not compute reward, cost, or termination signals. The full CMDP interface::

(obs, reward, cost, terminated, truncated, info)

is assembled by PowerEnv + a Task. Resources expose two read-only query methods:

  • obs() → observation dict for the RL agent (flattened by PowerEnv)
  • status() → full state dict for diagnostics, info channel, and costs

Cost convention: any field in status() whose key starts with cost_ is automatically collected by PowerEnv into the unified CMDP cost channel. Subclasses that detect constraint violations should expose them as cost_<name> fields (≥ 0, in physical units).

Physical safety contract: subclass step(action) implementations must clip actions to physically realisable bounds before updating internal state (e.g. SOC must never go below 0 or above 1). The amount clipped away may be reported as a cost_* field in status() for the CMDP cost channel, but internal state must never diverge or become unrepresentable.

status() base fields: current_p_mw, current_q_mvar, time_step, bus_id (int), local_v (float | None — per-unit bus voltage, None when parent grid has not run a power flow).

bus_id property writable

attach(parent, bus_id=None, name=None)

Attach resource to a parent hub or grid and register it.

Parameters:

Name Type Description Default
parent Any

The parent grid or hub to attach to.

required
bus_id int

Optional bus ID override.

None
name str

Optional custom name; auto-generated (e.g. 'solar_0') if None.

None

Returns:

Name Type Description
resource_id Optional[str]

The assigned resource ID.

detach()

Detach resource from its parent and unregister.

reset(*, seed=None, options=None, day_id=None)

Reset resource to initial state. Subclasses should call super() then apply resource-specific logic.

options may carry time_step / time_offset to align the resource's internal clock to the grid's episode start.

step(action)

Apply control action and update internal physical state.

This is a pure state mutator — it must not return a value. The caller (grid / PowerEnv) reads results afterwards via obs() and status().

Subclasses must override this method.

status()

Return current resource status dict.

Any key starting with cost_ is collected by PowerEnv as a CMDP safety cost (≥ 0, physical units, e.g. cost_clipped_power). Economic penalties/benefits go through econ_components(), not here.

Base fields always present

current_p_mw, current_q_mvar, time_step, bus_id, local_v (per-unit bus voltage, None if unavailable).

grid_obs()

Normalised feature vector for embedding this resource in a grid env.

Time encoding is excluded — the grid provides its own. Subclasses should override to expose type-specific features. Default: [current_p_norm].

grid_obs_names(rid)

Feature names for grid_obs(), prefixed with rid. Length must equal len(self.grid_obs()).

grid_action_bounds()

Physical (low, high) bounds for this resource's single grid action dimension.

Used by grid environments to construct the action space and to clip/denormalise actions before passing them to step().

grid_action_from_normalized(raw)

Map a normalised [-1, 1] scalar to physical action units.

Override for resources with non-standard semantics (e.g. curtailment-based renewables where +1 means no curtailment and the mapping is inverted). raw is already clipped to [-1, 1] by the caller.


powerzoo.envs.resource.battery.BatteryEnv(capacity_mwh=50.0, power_mw=20.0, eta_charge=None, eta_discharge=None, eta_roundtrip=None, efficiency=None, soc_min=0.1, soc_max=0.9, initial_soc=0.5, parent=None, bus_id=-1, normalize_actions=True, delta_t_minutes=15.0, cycle_cost_per_mwh=0.0, enable_q_control=False, s_rated_mva=None)

Bases: ResourceEnv

Battery Energy Storage System (physical sub-component, not standalone RL env).

For the full CMDP interface (obs, reward, cost, terminated, truncated, info), use a Task (e.g. battery_arbitrage) which wraps this resource inside PowerEnv.

Models a battery with: - State of Charge (SOC) dynamics - Separate charge / discharge efficiency - Charge/discharge power limits - SOC constraints

Sign convention (matches all other resources): current_p > 0: discharging (injecting power to the grid) current_p < 0: charging (drawing power from the grid)

Efficiency model

Discharging: grid receives p MW, battery loses p / eta_discharge MWh per hour Charging: grid supplies |p| MW, battery gains |p| * eta_charge MWh per hour Round-trip: eta_rt = eta_charge * eta_discharge

Default one-way efficiencies are 0.95 each (round-trip ≈ 0.9025). To use a round-trip shorthand with symmetric sqrt(η_rt) decomposition, pass eta_roundtrip. For the legacy default that matched η_rt = 0.95 with equal legs, use eta_roundtrip=0.95.

Parameters:

Name Type Description Default
capacity_mwh float

Energy capacity in MWh

50.0
power_mw float

Maximum charge/discharge power in MW

20.0
eta_charge Optional[float]

One-way charging efficiency ∈ (0, 1]. Default 0.95 if omitted and eta_roundtrip is not set.

None
eta_discharge Optional[float]

One-way discharging efficiency ∈ (0, 1]. Default 0.95 if omitted and eta_roundtrip is not set.

None
eta_roundtrip Optional[float]

Optional round-trip η_rt ∈ (0, 1]. When set, unspecified one-way sides use sqrt(eta_roundtrip); when both one-way values are explicit, this is ignored for assignment.

None
efficiency Optional[float]

Deprecated alias for eta_roundtrip.

None
soc_min float

Minimum SOC (0-1)

0.1
soc_max float

Maximum SOC (0-1)

0.9
initial_soc float

Initial SOC (0-1)

0.5

Initialize battery storage system

Parameters:

Name Type Description Default
capacity_mwh float

Energy capacity in MWh (default: 50)

50.0
power_mw float

Maximum power in MW (default: 20)

20.0
eta_charge Optional[float]

One-way charging efficiency ∈ (0, 1]. Omitted sides default to 0.95 unless eta_roundtrip is set (then sqrt(eta_roundtrip)).

None
eta_discharge Optional[float]

One-way discharging efficiency ∈ (0, 1].

None
eta_roundtrip Optional[float]

Round-trip η_rt ∈ (0, 1] for sqrt decomposition (optional).

None
efficiency Optional[float]

Deprecated; same as eta_roundtrip.

None
soc_min float

Minimum SOC 0-1 (default: 0.1)

0.1
soc_max float

Maximum SOC 0-1 (default: 0.9)

0.9
initial_soc float

Initial SOC 0-1 (default: 0.5)

0.5
parent Any

Parent grid or hub to attach to (optional)

None
bus_id int

Bus ID where this battery is connected (default: -1)

-1
normalize_actions bool

When True (default), action_space is [-1, 1] and step() maps -1 → -power_mw (charge), 0 → idle, 1 → +power_mw (discharge). When False, action_space is [-power_mw, power_mw] in physical MW.

True
delta_t_minutes float

Time step duration in minutes (default: 15). Overridden by parent grid's value after attach().

15.0
cycle_cost_per_mwh float

Cycle-degradation cost per MWh of energy throughput [$/MWh]. Returned via econ_components() as the 'cycle_degradation' key each step. Default 0.0 (no cost).

0.0
enable_q_control bool

When True, action becomes 2D [P, Q] with PQ circle constraint P² + Q² ≤ S_rated². Default False.

False
s_rated_mva Optional[float]

Inverter apparent power rating [MVA]. Defaults to power_mw (inverter sized to active power rating).

None

reset(*, seed=None, options=None, day_id=None)

Reset battery to initial state.

Parameters:

Name Type Description Default
seed

RNG seed passed to the parent class.

None
options

Optional dict of reset overrides: - randomize_soc (bool): when True, draw initial SOC uniformly from [soc_init_low, soc_init_high].

None
day_id Optional[int]

Episode day index passed to the parent class.

None

step(action=None)

Execute battery control action.

Sign convention: positive P = discharge (inject to grid), negative = charge. When enable_q_control=True, Q is limited by PQ circle: P²+Q² ≤ S².

obs(state=None)

Observation dict matching self.observation_space.

When enable_q_control=True adds q_mvar_norm (7-dim total).

status()

Return current battery status.

Includes all base fields (current_p_mw, current_q_mvar, time_step, bus_id, local_v) plus:

soc, soc_percent, energy_stored_mwh, capacity_mwh, power_mw, eta_charge, eta_discharge, efficiency_rt: physical state and configuration parameters.

p_discharge_headroom (MW): rated-power headroom toward discharge, computed as power_mw - max(current_p_mw, 0). This is the distance from the current grid-side setpoint to the rated discharge limit — not the SOC-constrained feasible margin. p_charge_headroom (MW): rated-power headroom toward charge, computed as power_mw + min(current_p_mw, 0). Same caveat: rated-power margin only, not energy-availability margin.

p_max_feasible_mw (MW): true SOC + rated-power constrained maximum discharge power at the current state (same constraint as _compute_feasible_power). Non-negative. Useful for diagnosing action-clipping in RL experiments. p_min_feasible_mw (MW): true SOC + rated-power constrained minimum power (most negative = maximum charge magnitude). Non-positive.

cost_clipped_power (MW, ≥ 0): absolute difference between the desired action and the feasible power after SOC / power-limit clipping. Zero when the action was fully feasible. Prefixed cost_ so PowerEnv automatically aggregates it into the CMDP safety cost channel (see ResourceEnv base class convention).

throughput_mwh (MWh, ≥ 0): cumulative energy throughput (|P|·Δt summed over all steps since last reset). Outer environments can use this to approximate degradation cost (e.g. multiply by a $/MWh wear coefficient).

get_soc_history()

Get SOC history for current episode

Returns:

Type Description
ndarray

Array of SOC values over time

grid_obs()

Grid-embedded observation (excludes time encoding).

P-only: [soc, p_discharge_max_norm, p_charge_max_norm, p_mw_norm] (4D) P+Q: [soc, p_discharge_max_norm, p_charge_max_norm, p_mw_norm, q_mvar_norm] (5D)

grid_obs_names(rid)


powerzoo.envs.resource.vehicle.VehicleEnv(parent=None, bus_id=-1, E_max_kWh=60.0, soc_init=0.8, soc_min=0.1, soc_max=0.95, soc_departure_min=0.8, p_charge_max_kW=7.0, p_discharge_max_kW=7.0, eta_charge=0.95, eta_discharge=0.95, commute_schedule=None, delta_t_minutes=15.0, normalize_actions=True)

Bases: ResourceEnv

Electric Vehicle resource (physical sub-component, not standalone RL env).

For the full CMDP interface, use a Task which wraps this inside PowerEnv.

Models an EV with multiple commute trips, charging when at home, and departure SOC requirements. Positive current_p means V2G (vehicle-to-grid); negative means G2V (grid-to-vehicle).

Supports flexible commute patterns in a day: - Simple: home -> work -> home - Complex: home -> work -> lunch -> work -> errands -> home

Initialize electric vehicle environment.

Parameters:

Name Type Description Default
parent Any

Parent grid or hub.

None
bus_id int

Bus ID where EV is connected.

-1
E_max_kWh float

Battery capacity (kWh), typical: 40–80 kWh.

60.0
soc_init float

Initial SOC [0, 1].

0.8
soc_min float

Minimum SOC [0, 1], typical: 0.1–0.2.

0.1
soc_max float

Maximum SOC [0, 1], typical: 0.9–0.95.

0.95
soc_departure_min float

Minimum SOC required at departure.

0.8
p_charge_max_kW float

Maximum charging power (kW), typical: 3.3–7.7.

7.0
p_discharge_max_kW float

Maximum V2G discharge power (kW).

7.0
eta_charge float

Charging efficiency (0, 1].

0.95
eta_discharge float

Discharging efficiency (0, 1].

0.95
commute_schedule List[Dict[str, float]]

List of daily trips, each dict with keys: - 'departure': hour [0, 24) - 'arrival': hour [0, 24) - 'energy_kWh': energy consumed (kWh) Defaults to a single trip (8 am–6 pm, 15 kWh).

None
delta_t_minutes float

Time step duration (minutes).

15.0
normalize_actions bool

If True, action space is normalised to [-1, 1].

True

reset(*, seed=None, options=None, day_id=None)

Reset vehicle to initial state.

step(action=None)

Apply charging/discharging action and update SOC and availability.

Execution order: state transitions (arrival / departure) are resolved before the charging action is applied. This means a vehicle arriving at time T can begin charging in the same step.

Action can be: - None → idle (0 MW) - dict with 'p_mw' → physical MW; positive = discharge (V2G), negative = charge (G2V). Always physical regardless of normalize_actions. - float / ndarray → when normalize_actions=True (default), treated as a normalised value and de-normalised via grid_action_from_normalized(); when False, treated as MW.

obs(state=None)

Return observation dict matching self.observation_space (9-dim).

Keys are defined by OBS_NAMES.

status()

Return current vehicle status.

Base fields (current_p_mw, current_q_mvar, time_step, bus_id, local_v) are provided by the base class.

Additional fields:

soc, capacity_mwh, soc_min, soc_max, soc_departure_min, is_home, time_of_day, departure_ready: physical state and configuration.

time_to_departure (h): hours until next scheduled departure.

time_to_arrival (h): hours until home arrival (0 when at home).

cost_clipped_power (MW, ≥ 0): |desired − feasible| power.

cost_unmet_energy (MWh, ≥ 0): energy shortfall at departure.

available_power()

Return available charge/discharge power considering SOC and availability.

check_departure_ready()

Check if vehicle meets departure SOC requirement.


powerzoo.envs.resource.renewable.RenewableEnv(parent=None, bus_id=-1, capacity_mw=100.0, profile_column=None, custom_data_loader=None, cf_array=None, delta_t_minutes=30.0, normalize_actions=True, curtailment_penalty_per_mwh=0.0, enable_q_control=False, s_rated_mva=None)

Bases: ResourceEnv

Renewable energy resource (physical sub-component, not standalone RL env).

For the full CMDP interface, use a Task which wraps this inside PowerEnv.

Time series data is loaded and aligned in attach(), not at construction: if a custom_data_loader is provided it is used; otherwise the parent grid's _time_series_data is used. The result is stored as a pre-aligned numpy array for O(1) step access.

Initialize renewable resource

Parameters:

Name Type Description Default
parent Any

Parent grid environment.

None
bus_id int

Bus ID to connect to.

-1
capacity_mw float

Installed capacity in MW.

100.0
profile_column Optional[str]

Semantic signal name (e.g. signals.SOLAR_AVAILABLE_MW). Legacy raw names ('Solar', 'Wind') are auto-mapped. If None, uses default signal based on resource type.

None
custom_data_loader Any

Custom DataLoader instance. If None, uses parent grid's data.

None
cf_array Optional[ndarray]

Direct capacity-factor array (third data path; mirrors JAX RenewableBundle.profiles). When provided, the resource bypasses the parent / loader-based data loading entirely and drives output from this array. Useful for behind-the-meter envs (e.g. DCMicrogridEnv) where there is no grid parent with a _time_series_data DataFrame. Shape (T,) where T is any positive length; indexing is cyclical (arr[t % T]). Values are clipped to [0, 1].

None
delta_t_minutes float

Time step in minutes

30.0
normalize_actions bool

When True (default), action_space is [-1, 1] and step() maps -1 → full curtailment, 1 → full output. When False, action_space is [0, 1] (physical curtailment fraction).

True
curtailment_penalty_per_mwh float

Economic penalty for curtailed renewable energy [$/MWh]. Returned via econ_components() as the 'curtailment' key each step. Default 0.0 (no penalty).

0.0
enable_q_control bool

If True, action is 2-D [curtailment_norm, q_norm] and obs includes q_mvar_norm. PQ circle constraint is applied (P-priority), matching BatteryBundle semantics. Default False.

False
s_rated_mva Optional[float]

Inverter apparent power rating [MVA]. Only used when enable_q_control=True. Defaults to capacity_mw.

None

reset(*, seed=None, options=None, day_id=None)

Reset renewable resource and return initial observation.

step(action=None)

Update renewable output based on time series data.

Parameters:

Name Type Description Default
action Any

Optional curtailment control. Accepted forms:

  • None → no curtailment (default)
  • float in [0, 1] → curtailment fraction (physical)
  • numpy.ndarray → first element used, same rules as float
  • dict → reads 'curtailment' key; always physical [0, 1], regardless of normalize_actions

When normalize_actions=True, float / ndarray actions are in [-1, 1] where +1 → no curtailment (full output) and -1 → full curtailment.

None

obs(state=None)

Observation dict matching self.observation_space.

Keys (alphabetical order — defines flattening order in PowerEnv):

P-only (enable_q_control=False): available_cf, p_mw_norm, time_cos, time_sin P+Q (enable_q_control=True): available_cf, p_mw_norm, q_mvar_norm, time_cos, time_sin

status()

Return current renewable resource status.

Includes all base fields (current_p_mw, current_q_mvar, time_step, bus_id, local_v) plus:

capacity_mw: installed capacity in MW. available_cf: weather-driven available capacity factor ∈ [0, 1] (fraction of capacity available before curtailment). available_p_mw: maximum power output before curtailment (MW). curtailed_p_mw: power curtailed this step (MW), i.e. available_p_mw - current_p_mw. output_ratio: actual output / installed capacity ∈ [0, 1] (after curtailment).

attach(parent, bus_id=None, name=None)

Attach resource to parent and load time series data.

When _available_cf is already populated (via the cf_array constructor argument or set_cf_array()) the parent / loader-based data load is skipped so the direct CF path takes precedence and no warning is emitted for the missing parent data.

grid_obs()

Grid-embedded observation (strips time encoding — grid provides its own).

P-only: [available_cf, p_mw_norm] P+Q: [available_cf, p_mw_norm, q_mvar_norm]

grid_obs_names(rid)

grid_action_from_normalized(raw)

Curtailment semantics: +1 → no curtailment (0.0), -1 → full curtailment (1.0).


powerzoo.envs.resource.renewable.SolarEnv(parent=None, bus_id=-1, capacity_mw=100.0, profile_column=None, custom_data_loader=None, cf_array=None, delta_t_minutes=30.0, normalize_actions=True, curtailment_penalty_per_mwh=0.0, enable_q_control=False, s_rated_mva=None)

Bases: RenewableEnv

Solar PV resource


powerzoo.envs.resource.renewable.WindEnv(parent=None, bus_id=-1, capacity_mw=100.0, profile_column=None, custom_data_loader=None, cf_array=None, delta_t_minutes=30.0, normalize_actions=True, curtailment_penalty_per_mwh=0.0, enable_q_control=False, s_rated_mva=None)

Bases: RenewableEnv

Wind turbine resource


powerzoo.envs.resource.flexload.FlexLoad(curtail_cap_mw=10.0, shift_cap_mw=10.0, shift_horizon=4, baseline_mw=50.0, curtail_cost_per_mwh=50.0, shift_cost_per_mwh=10.0, complementarity_penalty=100.0, price_ref=100.0, action_scale='unit', normalize_actions=None, parent=None, bus_id=-1, delta_t_minutes=15.0)

Bases: ResourceEnv

Flexible Load Demand Response Resource (physical sub-component, not standalone RL env).

Implements a two-action (curtailment + shift-out) demand response asset.

Sign convention: curtailment and shift-out both reduce net load at the bus, which is equivalent to injecting power (positive current_p_mw). Shift-in returns deferred load, reducing the injection.

For the full CMDP interface, use a Task which wraps this inside PowerEnv.

Parameters

curtail_cap_mw : float Maximum curtailment capacity [MW]. Default: 10.0. shift_cap_mw : float Maximum per-step demand shift capacity [MW]. Default: 10.0. shift_horizon : int Number of future steps over which deferred demand is uniformly released. Longer horizons reduce rebound severity. Default: 4. baseline_mw : float Nominal baseline demand [MW]. Reserved for profile normalisation; not currently used in the observation vector. Default: 50.0. curtail_cost_per_mwh : float Discomfort / compensation cost for curtailment [\(/MWh]. Default: 50.0. shift_cost_per_mwh : float Holding / discomfort cost rate for buffered deferred demand [\)/MWh]. Default: 10.0. complementarity_penalty : float Penalty coefficient [\(/MW] for co-activating curtailment and shift-out. Default: 100.0. price_ref : float Reference LMP for price normalisation in observation [\)/MWh]. Default: 100.0. action_scale : {'physical', 'unit', 'tanh'} Action space normalisation mode. Default: 'unit'. normalize_actions : bool or None Legacy compatibility parameter. If provided, overrides action_scale: True -> 'unit', False -> 'physical'. Default: None (use action_scale). parent : GridEnv or None Parent grid environment. bus_id : int Bus index where this asset is connected. delta_t_minutes : float Duration of each RL time step [min]. Default: 15.0.

reset(*, seed=None, options=None, day_id=None)

Reset to zero-action, empty-buffer state.

step(action=None)

Apply flexibility action for one time step.

Execution order: 1. Release any deferred demand due this step -> s_in(t) 2. Parse and scale the RL action -> c(t), s_out(t) 3. Clip to physical capacities 4. Buffer s_out(t) for future release 5. Compute net injection: dP = c(t) + s_out(t) - s_in(t) 6. Advance time step

Parameters

action : None | float | ndarray | dict - None or 0 -> no flexibility (idle) - ndarray shape (2,) -> [curtail_mw, shift_out_mw] (scaled) - dict -> keys 'curtail_mw', 'shift_out_mw'

obs(state=None)

Return observation dict matching self.observation_space.

status()

Return full status dict with physical state and CMDP cost signals.

CMDP cost fields: - cost_curtailment: discomfort/compensation for curtailed energy [$/step] - cost_shift_discomfort: holding cost for buffered demand [$/step] - cost_buffer_overflow: energy beyond shift horizon [MWh] - cost_simultaneous: complementarity violation penalty [$/step]


powerzoo.envs.resource.datacenter.DataCenterEnv(n_gpus=1000, gpu_idle_w=55.0, gpu_active_w=1100.0, p_base_mw=0.5, infer_gpu_peak=400, infer_gpu_eta=0.5, p_aux_frac=0.05, cop_ref=5.0, cop_decay=0.04, t_ref=20.0, ua_cooling=200.0, air_heat_fraction=1.0, p_cool_min_mw=0.05, c_thermal=500.0, h_wall=5.0, t_set_min=18.0, t_set_max=27.0, t_critical=35.0, train_cfg=None, finetune_cfg=None, parent=None, bus_id=-1, normalize_actions=True, delta_t_minutes=15.0)

Bases: ResourceEnv

AI Data Center resource (physical sub-component, not standalone RL env).

For the full CMDP interface, use a Task which wraps this inside PowerEnv.

RL action (3-D continuous): [r_train, r_finetune, cooling_setpoint] When normalize_actions=True (default) the action space is [-1, 1] and each element is linearly mapped to its physical range. When normalize_actions=False the action space is [0, 1].

- r_train          : fraction of *available* GPUs allocated to training
- r_finetune       : fraction of *available* GPUs allocated to finetuning
  (training and finetuning share the available pool proportionally, not
  sequentially — r_finetune is *not* a fraction of what remains after
  training is subtracted)
- cooling_setpoint : normalised setpoint mapped to [t_set_min, t_set_max]

Parameters

n_gpus : int Total GPU count in the data center (default 1000). gpu_idle_w : float Per-GPU idle power in watts (default 55, H100 measured). gpu_active_w : float Per-GPU system-level active power in watts (default 1100, approximating H100 SXM node total power divided by 8 GPUs). Includes CPU, NVSwitch, memory, and board losses. p_base_mw : float Baseline non-GPU IT power — networking, storage, mgmt nodes (MW). infer_gpu_peak : int Peak GPU count consumed by inference (diurnal profile amplitude). cop_ref : float Reference COP at t_ref degrees (default 5.0). cop_decay : float COP fractional decay per degree above t_ref (default 0.04). t_ref : float Reference outdoor temperature for COP (°C, default 20). c_thermal : float Thermal capacitance of the DC zone (kWh/°C, default 500). ua_cooling : float Cooling system heat-transfer coefficient (kW/°C, default 200). h_wall : float Building envelope heat-transfer coefficient (kW/°C, default 5). t_set_min, t_set_max : float Cooling setpoint range (°C, default 18–27, ASHRAE). t_critical : float Over-temperature safety threshold (°C, default 35). p_aux_frac : float Auxiliary power as fraction of IT power (default 0.05). infer_gpu_eta : float GPU utilisation factor for inference workloads (default 0.5). air_heat_fraction : float Fraction of IT heat entering the air zone (default 1.0 = pure air-cooled; set ~0.2 for high-density liquid-cooled clusters). p_cool_min_mw : float Minimum standby cooling power in MW (default 0.05). Real cooling plants (fans, pumps, controls) never draw zero even when the zone is below setpoint. train_cfg, finetune_cfg : dict or None Task generation parameters (see _DEFAULT_TRAIN_CFG).

reset(*, seed=None, options=None, day_id=None)

step(action=None, *, t_outdoor_override=None, gpus_infer_override=None)

Execute one time step.

Parameters:

Name Type Description Default
action

None, ndarray(3,), or dict with keys 'r_train', 'r_finetune', 'cooling_setpoint'.

None
t_outdoor_override

Optional [°C] outdoor temperature to inject for this step (formal API used by composite envs like DCMicrogridEnv to feed exogenous weather profiles). Falls back to self._override_t_outdoor (deprecated private hook) or _get_outdoor_temp() if not provided.

None
gpus_infer_override

Optional integer override for the inference GPU count this step (for injecting CPU-utilisation profiles). Falls back to self._override_gpus_infer or the synthetic diurnal curve.

None

obs(state=None)

Observation dict (11 fields).

status()

Return current data center status.

cost_overtemp (°C, ≥ 0): zone temperature above critical threshold. Zero when within safe limits.

Custom Resource Lifecycle and Initialization

When implementing custom physical asset environments (e.g., storage, generators) in PowerZoo, you must adhere strictly to the following lifecycle and initialization constraints:

  1. Deferred Parent Attachment During node attachment via attach(parent_bus_id), the delta_t_minutes parameter is synchronized directly from the underlying grid-level environment or parent node. Internal definitions of _dt_h are deprecated; unified access must use self.dt_hours synchronized post-attachment to maintain system-wide temporal consistency.

  2. _complete_resource_init() Hook To prevent crashes or deadlocks triggered by action space synchronization before a subclass finishes building its action_space or observation_space, all custom Resource classes inheriting from BaseEnv must explicitly call self._complete_resource_init() as the final step in their __init__ method. This guarantees final dependency assembly and validation correctly resolves.