SolarBatteryHouse#

This is the main environment provided by Bauwerk. The environment consists of a single home with the following electrical components:

  • Battery: can be controlled by setting battery (dis)charging rate.

  • Solar photovoltaic installation: provides energy when the sun allows for it but can’t be directly controlled.

  • Residential electrical load: represents energy usage that needs to be covered but can’t be controlled.

  • Grid connection: allows to buy or sell energy to the grid, can’t be controlled directly. All energy needs of the system must be satisfied and energy will be bought automatically accordingly. Similarly, excess energy is automatically sold.

The diagram below illustrates the setup of the environment.

2283325e45de46eeb6ca8b19e1ae358c

Creating environment#

The code snippet below shows how to create an SolarBatteryHouse environment

[1]:
import bauwerk
import gym

env = gym.make("bauwerk/SolarBatteryHouse-v0")
<__array_function__ internals>:200: RuntimeWarning: overflow encountered in cast

Action and Observation Spaces#

The action space simply consists of a single float number between \(-1.0\) and \(1.0\), representing how much the battery should be charged (if \(>0\)) or discharged (if \(<0\)). The boundaries \(-1.0\) and \(1.0\) represent (approximately) the maximum amount the battery can be discharged/charged in a single time step. Note that (dis-)charging by these maximum amounts may often not be possible. In this case, the closest action will be taken. For example, if the battery is almost full, action \(1.0\) may actually result in charging as if action \(0.1\) was given.

The action space can inspected as shown below.

[2]:
env.action_space
[2]:
Box([-1.], [1.], (1,), float32)

The observation space consists of a dictionary with the latest battery content (battery_cont), load (load), photovoltaic generation (pv_gen) and the current time of day (time_of_day).

[3]:
dict(env.observation_space.items())
[3]:
{'battery_cont': Box([0.], [7.5], (1,), float32),
 'load': Box([0.], [3.936], (1,), float32),
 'pv_gen': Box([0.], [3.013], (1,), float32),
 'time_of_day': Box([-1. -1.], [1. 1.], (2,), float32)}

Further environments parameters#

All environment configuration parameters of the SolarBatteryHouse environment are stored in the following attribute:

[4]:
env.cfg
[4]:
EnvConfig(time_step_len=1.0, episode_len=8759, grid_charging=True, infeasible_control_penalty=False, obs_keys=['load', 'pv_gen', 'battery_cont', 'time_of_day'], action_space_type='relative', dtype='float32', battery_size=7.5, battery_chemistry='NMC', battery_start_charge=0.0, data_start_index=0, solar_data=None, solar_scaling_factor=3.5, solar_noise_magnitude=0.0, load_data=None, load_scaling_factor=4.5, load_noise_magnitude=0.0, grid_peak_threshold=2.0, grid_base_price=0.25, grid_peak_price=1.25, grid_sell_price=0.05, grid_selling_allowed=True, solar=None, battery=None, load=None, grid=None)

Optimal control#

Bauwerk supports the computation of the optimal control of SolarBatteryHouse environments. The following snippet computes all the optimal actions for the current episode of the environment env.

Note: computing optimal control as below requires the cvxpy package. This can be installed by running pip install bauwerk[cvxpy].

[5]:
optimal_actions, cvxpy_problem = bauwerk.solve(env)
optimal_actions
[5]:
array([[ 0.   ],
       [ 0.   ],
       [-0.   ],
       ...,
       [-0.178],
       [-0.04 ],
       [-0.002]], dtype=float32)
[ ]: