Skip to content

Commit

Permalink
Merge pull request #19 from tobirohrer/feature/ruff
Browse files Browse the repository at this point in the history
Added ruff
  • Loading branch information
tobirohrer authored Jan 2, 2024
2 parents c77c7bf + 60d7a91 commit 0723fae
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 33 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ jobs:
run: pytest ./tests

- name: Type checking with mypy
run: mypy building_energy_storage_simulation
run: mypy building_energy_storage_simulation

- name: Code style checking with ruff
run: ruff check .
12 changes: 12 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Same as Black.
line-length = 127
# Assume Python 3.8
target-version = "py38"
# See https://beta.ruff.rs/docs/rules/
select = ["E", "F", "B", "UP", "C90", "RUF", "I", "N", "B", "SIM"]
# B028: Ignore explicit stacklevel`
# RUF013: Too many false positives (implicit optional)
ignore = ["B028", "RUF013"]

[extend-per-file-ignores]
"__init__.py" = ["F401", "F403"]
5 changes: 3 additions & 2 deletions building_energy_storage_simulation/building_simulation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Tuple, Iterable, Union
from typing import Iterable, Tuple, Union

import numpy as np

Expand Down Expand Up @@ -26,7 +26,8 @@ class BuildingSimulation:
def __init__(self,
electricity_load_profile: Iterable = load_profile('electricity_load_profile.csv', 'Load [kWh]'),
solar_generation_profile: Iterable = load_profile('solar_generation_profile.csv', 'Generation [kWh]'),
electricity_price: Union[Iterable, float] = load_profile('electricity_price_profile.csv', 'Day Ahead Auction'),
electricity_price: Union[Iterable, float] = load_profile('electricity_price_profile.csv',
'Day Ahead Auction'),
battery_capacity: float = 100,
max_battery_charge_per_timestep: float = 20
):
Expand Down
6 changes: 3 additions & 3 deletions building_energy_storage_simulation/environment.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Tuple, Optional, Union, List, Iterable, Any
from collections.abc import MutableSequence
from typing import Any, Iterable, List, Optional, Tuple, Union

import gymnasium as gym
import numpy as np
from gymnasium.core import ActType, ObsType, RenderFrame
from gymnasium.core import RenderFrame

from building_energy_storage_simulation.building_simulation import BuildingSimulation


Expand Down
2 changes: 1 addition & 1 deletion building_energy_storage_simulation/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pkg_resources
import pandas as pd
import pkg_resources


def load_profile(filename: str, column_name: str) -> pd.Series:
Expand Down
16 changes: 11 additions & 5 deletions example_solutions/deep_reinforcement_learning/evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
from stable_baselines3.common.vec_env import DummyVecEnv, VecNormalize

from building_energy_storage_simulation import BuildingSimulation, Environment
from example_solutions.deep_reinforcement_learning.train import RESULT_PATH, NUM_FORECAST_STEPS
from example_solutions.helper import read_data, TEST_INDEX_START, TEST_INDEX_END, BATTERY_POWER, BATTERY_CAPACITY, \
plot_control_trajectory
from example_solutions.deep_reinforcement_learning.train import NUM_FORECAST_STEPS, RESULT_PATH
from example_solutions.helper import (
BATTERY_CAPACITY,
BATTERY_POWER,
TEST_INDEX_END,
TEST_INDEX_START,
plot_control_trajectory,
read_data,
)
from example_solutions.observation_wrapper import ObservationWrapper


Expand All @@ -17,7 +23,7 @@ def evaluate(env, agent=None):
done = False
obs = env.reset()
while not done:
if agent is None:
if agent is None: # noqa
action = [[0]]
else:
action = [agent.predict(obs, deterministic=True)[0][0]]
Expand All @@ -44,7 +50,7 @@ def evaluate(env, agent=None):
# Plot evolution of reward during training
try:
plot_results(RESULT_PATH, x_axis='timesteps', task_name='title', num_timesteps=None)
except:
except: # noqa
print('Training Reward Plot could not be created')

load, price, generation = read_data()
Expand Down
5 changes: 3 additions & 2 deletions example_solutions/deep_reinforcement_learning/train.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from stable_baselines3.common.vec_env import DummyVecEnv, VecNormalize

from building_energy_storage_simulation import BuildingSimulation, Environment
from example_solutions.helper import read_data, TEST_INDEX_START, BATTERY_CAPACITY, BATTERY_POWER
from example_solutions.helper import BATTERY_CAPACITY, BATTERY_POWER, TEST_INDEX_START, read_data
from example_solutions.observation_wrapper import ObservationWrapper

NUM_FORECAST_STEPS = 8
Expand Down Expand Up @@ -41,6 +41,7 @@
# Train :-)
model = SAC("MlpPolicy", env, verbose=1, gamma=0.95)
model.learn(total_timesteps=200_000)
# Store the trained Model and environment stats (which are needed as we are standardizing the observations and reward using VecNormalize())
# Store the trained Model and environment stats (which are needed as we are standardizing the observations and
# reward using VecNormalize())
model.save(RESULT_PATH + 'model')
env.save(RESULT_PATH + 'env.pkl')
5 changes: 2 additions & 3 deletions example_solutions/helper.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from pathlib import Path

import pandas as pd
import numpy as np
from typing import Tuple

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

# Start and end Index of data used for testing
Expand Down
9 changes: 5 additions & 4 deletions example_solutions/model_predictive_control.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import pyomo.environ as pyo
import numpy as np
import pyomo.environ as pyo
from helper import BATTERY_CAPACITY, BATTERY_POWER, TEST_INDEX_END, TEST_INDEX_START, plot_control_trajectory, read_data
from optimal_control_problem import build_optimization_problem

from building_energy_storage_simulation import BuildingSimulation, Environment
from optimal_control_problem import build_optimization_problem
from helper import read_data, TEST_INDEX_END, TEST_INDEX_START, BATTERY_POWER, BATTERY_CAPACITY, plot_control_trajectory

FORECAST_LENGTH = 24

Expand Down Expand Up @@ -43,7 +43,8 @@ def normalize_to_minus_one_to_one(x, min_value, max_value):

optimization_problem = build_optimization_problem(residual_fixed_load=residual_load_forecast,
price=price_forecast,
soc=soc / BATTERY_CAPACITY * 100, # Convert SOC due to different SOC definitions
# Convert SOC due to different SOC definitions
soc=soc / BATTERY_CAPACITY * 100,
battery_capacity=BATTERY_CAPACITY,
battery_power=BATTERY_POWER)
solver.solve(optimization_problem, tee=True)
Expand Down
7 changes: 3 additions & 4 deletions example_solutions/optimal_control_problem.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import pyomo.environ as pyo
import numpy as np

from helper import read_data, TEST_INDEX_END, TEST_INDEX_START, BATTERY_CAPACITY, BATTERY_POWER, plot_control_trajectory
import pyomo.environ as pyo
from helper import BATTERY_CAPACITY, BATTERY_POWER, TEST_INDEX_END, TEST_INDEX_START, plot_control_trajectory, read_data


def build_optimization_problem(residual_fixed_load, price, soc, battery_power, battery_capacity, delta_time_hours=1):
Expand All @@ -20,7 +19,7 @@ def build_optimization_problem(residual_fixed_load, price, soc, battery_power, b

def obj_expression(m):
# pyo.log to make the objective expression smooth and therefore solvable
return sum([price[i] * pyo.log(1 + pyo.exp((m.power[i] + residual_fixed_load[i]))) for i in time])
return sum([price[i] * pyo.log(1 + pyo.exp(m.power[i] + residual_fixed_load[i])) for i in time])

m.OBJ = pyo.Objective(rule=obj_expression, sense=pyo.minimize)

Expand Down
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from distutils.core import setup
from pathlib import Path

this_directory = Path(__file__).parent
long_description = (this_directory / "README.md").read_text()

setup(name='building_energy_storage_simulation',
version='0.9.2',
version='0.9.3',
description='A simulation of a building to optimize energy storage utilization.',
long_description=long_description,
long_description_content_type='text/markdown',
Expand All @@ -31,7 +32,8 @@
"pytest",
"mypy",
"pandas-stubs",
"types-setuptools"
"types-setuptools",
"ruff"
]
}
)
4 changes: 2 additions & 2 deletions tests/test_building_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

def test_energy_consumption_is_trimmed_to_0():
sim = BuildingSimulation(electricity_load_profile=[0], solar_generation_profile=[100], electricity_price=[1])
# Don´t charge the battery, meaning don´t do anything with the 100kWh energy we gained from the solar system.
# Don't charge the battery, meaning don't do anything with the 100kWh energy we gained from the solar system.
electricity_consumption, excess_energy = sim.simulate_one_step(0)
# Still the consumption is 0, as we loose excess electricity which we do not use to charge the battery.
assert electricity_consumption == 0
Expand All @@ -29,6 +29,6 @@ def test_simulation_scalar_electricity_price_converted_into_profile(electricity_

def test_simulation_throws_when_data_profiles_have_unequal_length():
with pytest.raises(Exception) as exception_info:
sim = BuildingSimulation(electricity_load_profile=[0, 0, 0],
BuildingSimulation(electricity_load_profile=[0, 0, 0],
solar_generation_profile=[0, 0])
assert exception_info.errisinstance(ValueError)
8 changes: 4 additions & 4 deletions tests/test_environment.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from building_energy_storage_simulation.building_simulation import BuildingSimulation
import numpy as np
import pytest

from building_energy_storage_simulation import Environment
import pytest
import numpy as np
from building_energy_storage_simulation.building_simulation import BuildingSimulation


@pytest.fixture(scope='module')
Expand Down Expand Up @@ -37,7 +37,7 @@ def test_terminated_at_timelimit_reached(data_profile_length, num_forecasting_st
max_timesteps=data_profile_length - num_forecasting_steps)
env.reset()
print(range(data_profile_length - num_forecasting_steps))
for i in range(data_profile_length - num_forecasting_steps):
for _ in range(data_profile_length - num_forecasting_steps):
obs, reward, terminated, trunc, info = env.step(0)
assert terminated is True

Expand Down

0 comments on commit 0723fae

Please sign in to comment.