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

Added mypy #18

Merged
merged 4 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 6 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ on:
branches: [ "master" ]

jobs:
test:

checkup:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: install dependencies
run: pip install .[tests]
run: pip install .[dev]

- name: Run Tests with pytest
run: pytest ./tests
run: pytest ./tests

- name: Type checking with mypy
run: mypy building_energy_storage_simulation
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
__pycache__
**.egg-info
.ipynb_checkpoints
docs/build
docs/build
build/
dist/
2 changes: 2 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[mypy]
disallow_untyped_defs = True
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ or if you want to continue developing the package:

```
git clone https://github.com/tobirohrer/building-energy-storage-simulation.git && cd building-energy-storage-simulation
pip install -e .[docs,tests]
pip install -e .[dev]
```

## Usage
Expand Down
5 changes: 2 additions & 3 deletions building_energy_storage_simulation/battery.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ def __init__(self,
self.capacity = capacity
self.initial_state_of_charge = initial_state_of_charge
self.state_of_charge = initial_state_of_charge
pass

def use(self, amount: float):
def use(self, amount: float) -> float:
"""
Using means charging or discharging the battery.

Expand Down Expand Up @@ -52,7 +51,7 @@ def use(self, amount: float):
self.state_of_charge += amount
return electricity_used

def reset(self):
def reset(self) -> None:
"""
Resetting the `state_of_charge` of the battery to the `initial_state_of_charge`.
"""
Expand Down
6 changes: 2 additions & 4 deletions building_energy_storage_simulation/building_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ def __init__(self,

self.step_count = 0
self.start_index = 0
pass

def reset(self):
def reset(self) -> None:
"""

1. Resetting the state of the building by calling `reset()` method from the battery class.
Expand All @@ -59,7 +58,6 @@ def reset(self):

self.battery.reset()
self.step_count = 0
pass

def simulate_one_step(self, action: float) -> Tuple[float, float]:
"""
Expand Down Expand Up @@ -97,7 +95,7 @@ def simulate_one_step(self, action: float) -> Tuple[float, float]:
self.step_count += 1
return electricity_consumption_this_timestep, electricity_price_this_timestep

def _check_data_profiles_same_length(self):
def _check_data_profiles_same_length(self) -> None:
if len(self.solar_generation_profile) == len(self.electricity_load_profile) == len(self.electricity_price):
pass
else:
Expand Down
27 changes: 13 additions & 14 deletions building_energy_storage_simulation/environment.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Tuple, Optional, Union, List
from typing import Tuple, Optional, Union, List, Iterable, Any
from collections.abc import MutableSequence

import gymnasium as gym
Expand Down Expand Up @@ -50,7 +50,6 @@ def __init__(self,
low=-np.inf,
high=np.inf,
dtype=np.float32)
pass

def render(self) -> Optional[Union[RenderFrame, List[RenderFrame]]]:
"""
Expand All @@ -59,7 +58,7 @@ def render(self) -> Optional[Union[RenderFrame, List[RenderFrame]]]:

pass

def reset(self, seed=None, options=None) -> Tuple[ObsType, dict]:
def reset(self, seed: Union[int, None] = None, options: Any = None) -> Tuple[np.ndarray, dict]:
"""
Resetting the state of the simulation by calling `reset()` method from the simulation class.

Expand All @@ -77,7 +76,7 @@ def reset(self, seed=None, options=None) -> Tuple[ObsType, dict]:
self.building_simulation.start_index = int(np.random.uniform(0, latest_possible_start_time_step))
return self.get_observation(), {}

def step(self, action: ActType) -> Tuple[ObsType, float, bool, bool, dict]:
def step(self, action: Union[float, Iterable[float]]) -> Tuple[np.ndarray, float, bool, bool, dict]:
"""
Perform one step, which is done by:

Expand All @@ -89,7 +88,7 @@ def step(self, action: ActType) -> Tuple[ObsType, float, bool, bool, dict]:
action represents the fraction of `max_battery_charge_per_timestep` which should be used to charge or
discharge the battery. 1 represents the maximum possible amount of energy which can be used to charge the
battery per time step.
:type action: float
:type action: float or [float]
:returns:
Tuple of:
1. observation
Expand All @@ -103,19 +102,19 @@ def step(self, action: ActType) -> Tuple[ObsType, float, bool, bool, dict]:
"""

if hasattr(action, "__len__"):
action = action[0]
electricity_consumption, electricity_price = self.building_simulation.simulate_one_step(action)
action = action[0] # type: ignore
electricity_consumption, electricity_price = self.building_simulation.simulate_one_step(action) # type: ignore
reward = Environment.calc_reward(electricity_consumption, electricity_price)
observation = self.get_observation()
return observation, reward, self._get_terminated(), False, {'electricity_consumption': electricity_consumption,
'electricity_price': electricity_price}

def _get_terminated(self):
def _get_terminated(self) -> bool:
if self.building_simulation.step_count >= self.max_timesteps:
return True
return False

def get_observation(self):
def get_observation(self) -> np.ndarray:
current_index = self.building_simulation.start_index + self.building_simulation.step_count
sim = self.building_simulation
electric_load_forecast = sim.electricity_load_profile[current_index: current_index + self.num_forecasting_steps]
Expand All @@ -127,23 +126,23 @@ def get_observation(self):
solar_gen_forecast = self._randomize_forecast(solar_gen_forecast)
energy_price_forecast = self._randomize_forecast(energy_price_forecast)

return np.concatenate(([self.building_simulation.battery.state_of_charge],
return np.concatenate(([self.building_simulation.battery.state_of_charge], # type: ignore
electric_load_forecast,
solar_gen_forecast,
energy_price_forecast),
axis=0)

@staticmethod
def _randomize_forecast(forecast: MutableSequence,
def _randomize_forecast(forecast: np.ndarray,
standard_deviation_start: float = 0.2,
standard_deviation_end: float = 1.0) -> MutableSequence:
standard_deviation_end: float = 1.0) -> np.ndarray:
# gamma can be interpreted as the quantification of the increase of uncertainty per time step.
gamma = standard_deviation_end - standard_deviation_start
for i in range(len(forecast)):
std = standard_deviation_end - gamma ** i
forecast[i] = forecast[i] + np.random.normal(0, std)
return forecast
return np.array(forecast)

@staticmethod
def calc_reward(electricity_consumption, electricity_price):
def calc_reward(electricity_consumption: float, electricity_price: float) -> float:
return -1 * electricity_consumption * electricity_price
13 changes: 7 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
long_description = (this_directory / "README.md").read_text()

setup(name='building_energy_storage_simulation',
version='0.9.0',
version='0.9.2',
description='A simulation of a building to optimize energy storage utilization.',
long_description=long_description,
long_description_content_type='text/markdown',
Expand All @@ -26,11 +26,12 @@
"numpy"
],
extras_require={
"docs": [
"sphinx"
],
"tests": [
"pytest"
"dev": [
"sphinx",
"pytest",
"mypy",
"pandas-stubs",
"types-setuptools"
]
}
)