Skip to content

Commit

Permalink
Custom Interval Data & Network Charges (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
ADGEfficiency authored Sep 14, 2024
1 parent 7933a2b commit 558be05
Show file tree
Hide file tree
Showing 34 changed files with 1,001 additions and 259 deletions.
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ TEST_ARGS =
export

test: setup-test test-docs
pytest tests --cov=energypylinear --cov-report=html -n $(PARALLEL) --color=yes --durations=5 --verbose --ignore tests/phmdoctest $(TEST_ARGS)
pytest tests --cov=energypylinear --cov-report=html --cov-report=term-missing -n $(PARALLEL) --color=yes --durations=5 --verbose --ignore tests/phmdoctest $(TEST_ARGS)
# -coverage combine
# -coverage html
-coverage report
Expand All @@ -56,7 +56,7 @@ generate-test-docs: setup-test
bash ./tests/generate-test-docs.sh

test-docs: setup-test generate-test-docs
pytest tests/phmdoctest -n $(PARALLEL) --dist loadfile --color=yes --verbose $(TEST_ARGS)
pytest tests/phmdoctest -n 1 --dist loadfile --color=yes --verbose $(TEST_ARGS)


# ----- CHECK -----
Expand All @@ -71,7 +71,7 @@ static: setup-static
rm -rf ./tests/phmdoctest
mypy --version
mypy $(MYPY_ARGS) ./energypylinear
mypy $(MYPY_ARGS) ./tests
mypy $(MYPY_ARGS) ./tests --explicit-package-bases

lint: setup-check
rm -rf ./tests/phmdoctest
Expand All @@ -81,13 +81,13 @@ lint: setup-check
ruff format --check **/*.py
poetry check

CHECK_DOCSTRINGS=./energypylinear/assets/battery.py ./energypylinear/objectives.py
CHECK_DOCSTRINGS=./energypylinear/objectives.py ./energypylinear/assets/battery.py ./energypylinear/assets/renewable_generator.py

# currently only run manually
lint-docstrings:
flake8 --extend-ignore E501 --exclude=__init__.py,poc --exit-zero $(CHECK_DOCSTRINGS)
pydocstyle $(CHECK_DOCSTRINGS)
pylint $(CHECK_DOCSTRINGS)
# pylint $(CHECK_DOCSTRINGS)


# ----- FORMATTING -----
Expand Down
20 changes: 11 additions & 9 deletions docs/docs/assets/battery.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ asset = epl.Battery(
freq_mins=60,
initial_charge_mwh=1,
final_charge_mwh=3,
name="battery"
name="battery",
include_spill=True
)
simulation = asset.optimize()

Expand All @@ -36,12 +37,13 @@ assert all(
"site-import_power_mwh",
"site-export_power_mwh",
"site-electricity_prices",
"site-export_electricity_prices",
"site-electricity_carbon_intensities",
"site-gas_prices",
"site-electric_load_mwh",
"site-high_temperature_load_mwh",
"site-low_temperature_load_mwh",
"site-low_temperature_generation_mwh",
"site-gas_prices",
"site-electric_load_mwh",
"spill-electric_generation_mwh",
"spill-electric_load_mwh",
"spill-high_temperature_generation_mwh",
Expand All @@ -68,7 +70,7 @@ assert all(
"total-spills_mwh",
"total-electric_loss_mwh",
"site-electricity_balance_mwh",
]
],
)
```

Expand Down Expand Up @@ -153,11 +155,11 @@ print(balance)

```
input accumulation output balance import generation export load charge discharge loss spills soc
0 0.444444 -0.444444 0.0 True 0.444444 0.0 0.0 0.0 0.444444 0.0 0.044444 0.0 0.0
1 2.000000 -2.000000 0.0 True 2.000000 0.0 0.0 0.0 2.000000 0.0 0.200000 0.0 0.0
2 0.000000 2.000000 2.0 True 0.000000 0.0 2.0 0.0 0.000000 2.0 0.000000 0.0 0.0
3 2.000000 -2.000000 0.0 True 2.000000 0.0 0.0 0.0 2.000000 0.0 0.200000 0.0 0.0
4 0.000000 2.000000 2.0 True 0.000000 0.0 2.0 0.0 0.000000 2.0 0.000000 0.0 0.0
0 0.444444 -0.444444 0.0 True 0.444444 0.0 0.0 0 0.444444 0.0 0.044444 0.0 0.0
1 2.000000 -2.000000 0.0 True 2.000000 0.0 0.0 0 2.000000 0.0 0.200000 0.0 0.0
2 0.000000 2.000000 2.0 True 0.000000 0.0 2.0 0 0.000000 2.0 0.000000 0.0 0.0
3 2.000000 -2.000000 0.0 True 2.000000 0.0 0.0 0 2.000000 0.0 0.200000 0.0 0.0
4 0.000000 2.000000 2.0 True 0.000000 0.0 2.0 0 0.000000 2.0 0.000000 0.0 0.0
```

In the first interval, we charge the battery with `0.444444 MWh` - `0.4 MWh` goes into increasing the battery state of charge from `0.0 MWh` to `0.4 MWh`, with the balance `0.044444 MWh` going to battery losses.
Expand Down
14 changes: 4 additions & 10 deletions docs/docs/assets/chp.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ asset = epl.CHP(
low_temperature_efficiency_pct=0.2,
electricity_prices=[100, 50, 200, -100, 0, 200, 100, -100],
high_temperature_load_mwh=[100, 50, 200, 40, 0, 200, 100, 100],
low_temperature_load_mwh=20,
low_temperature_load_mwh=20
)

simulation = asset.optimize()
Expand All @@ -47,19 +47,13 @@ assert all(
"site-import_power_mwh",
"site-export_power_mwh",
"site-electricity_prices",
"site-export_electricity_prices",
"site-electricity_carbon_intensities",
"site-gas_prices",
"site-electric_load_mwh",
"site-high_temperature_load_mwh",
"site-low_temperature_load_mwh",
"site-low_temperature_generation_mwh",
"site-gas_prices",
"site-electric_load_mwh",
"spill-electric_generation_mwh",
"spill-electric_load_mwh",
"spill-high_temperature_generation_mwh",
"spill-low_temperature_generation_mwh",
"spill-high_temperature_load_mwh",
"spill-low_temperature_load_mwh",
"spill-gas_consumption_mwh",
"chp-electric_generation_mwh",
"chp-gas_consumption_mwh",
"chp-high_temperature_generation_mwh",
Expand Down
8 changes: 5 additions & 3 deletions docs/docs/assets/evs.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ asset = epl.EVs(
charger_turndown=0.1,
electricity_prices=electricity_prices,
charge_events=charge_events,
include_spill=True
)

simulation = asset.optimize()
Expand All @@ -40,12 +41,13 @@ assert all(
"site-import_power_mwh",
"site-export_power_mwh",
"site-electricity_prices",
"site-export_electricity_prices",
"site-electricity_carbon_intensities",
"site-gas_prices",
"site-electric_load_mwh",
"site-high_temperature_load_mwh",
"site-low_temperature_load_mwh",
"site-low_temperature_generation_mwh",
"site-gas_prices",
"site-electric_load_mwh",
"spill-electric_generation_mwh",
"spill-electric_load_mwh",
"spill-high_temperature_generation_mwh",
Expand Down Expand Up @@ -100,7 +102,7 @@ assert all(
"total-spills_mwh",
"total-electric_loss_mwh",
"site-electricity_balance_mwh",
]
],
)
```

Expand Down
13 changes: 9 additions & 4 deletions docs/docs/assets/heat-pump.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ asset = epl.HeatPump(
electricity_prices=[100, -100],
high_temperature_load_mwh=3.0,
low_temperature_generation_mwh=3.0,
include_spill=True
)
simulation = asset.optimize(verbose=False)
print(
Expand All @@ -43,12 +44,13 @@ assert all(
"site-import_power_mwh",
"site-export_power_mwh",
"site-electricity_prices",
"site-export_electricity_prices",
"site-electricity_carbon_intensities",
"site-gas_prices",
"site-electric_load_mwh",
"site-high_temperature_load_mwh",
"site-low_temperature_load_mwh",
"site-low_temperature_generation_mwh",
"site-gas_prices",
"site-electric_load_mwh",
"spill-electric_generation_mwh",
"spill-electric_load_mwh",
"spill-high_temperature_generation_mwh",
Expand All @@ -75,7 +77,7 @@ assert all(
"total-spills_mwh",
"total-electric_loss_mwh",
"site-electricity_balance_mwh",
]
],
)
```

Expand Down Expand Up @@ -126,6 +128,7 @@ asset = epl.HeatPump(
electricity_prices=[100, -100],
high_temperature_load_mwh=3.0,
low_temperature_generation_mwh=4.0,
include_spill=True
)
simulation = asset.optimize(verbose=4)
print(simulation.results[
Expand Down Expand Up @@ -171,6 +174,7 @@ asset = epl.HeatPump(
electricity_prices=[-100, -100, -100],
high_temperature_load_mwh=[3.0, 0.5, 3.0],
low_temperature_generation_mwh=[4.0, 4.0, 0.5],
include_spill=True,
include_valve=False
)
simulation = asset.optimize(
Expand Down Expand Up @@ -219,7 +223,8 @@ asset = epl.HeatPump(
electricity_prices=[-100, -100, -100],
high_temperature_load_mwh=[3.0, 0.5, 3.0],
low_temperature_generation_mwh=[4.0, 4.0, 0.0],
include_valve=True
include_valve=True,
include_spill=True,
)
simulation = asset.optimize(
verbose=4,
Expand Down
7 changes: 4 additions & 3 deletions docs/docs/assets/renewable-generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ assert all(
"site-import_power_mwh",
"site-export_power_mwh",
"site-electricity_prices",
"site-export_electricity_prices",
"site-electricity_carbon_intensities",
"site-gas_prices",
"site-electric_load_mwh",
"site-high_temperature_load_mwh",
"site-low_temperature_load_mwh",
"site-low_temperature_generation_mwh",
"site-gas_prices",
"site-electric_load_mwh",
"wind-electric_generation_mwh",
"total-electric_generation_mwh",
"total-electric_load_mwh",
Expand All @@ -38,7 +39,7 @@ assert all(
"total-spills_mwh",
"total-electric_loss_mwh",
"site-electricity_balance_mwh",
]
],
)
```

Expand Down
88 changes: 88 additions & 0 deletions docs/docs/how-to/custom-interval-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
Interval data is a key input to an `energypylinear` simulation.

By default, `energypylinear` accepts interval data for things like electricity prices, carbon intensities and site electricity and heat consumption:

<!--phmdoctest-mark.skip-->
```python
--8<-- "energypylinear/assets/site.py:site"
```

These arguments are passed to the `SiteIntervalData` object, which is responsible for managing interval data for a site:

```python
import energypylinear as epl

asset = epl.Battery(electricity_prices=[100, 50, 200])
print(asset.site.cfg.interval_data)
```

```
electricity_prices=array([100., 50., 200.]) export_electricity_prices=array([100., 50., 200.]) electricity_carbon_intensities=array([0.1, 0.1, 0.1]) gas_prices=array([20, 20, 20]) electric_load_mwh=array([0, 0, 0]) high_temperature_load_mwh=array([0, 0, 0]) low_temperature_load_mwh=array([0, 0, 0]) low_temperature_generation_mwh=array([0, 0, 0]) idx=array([0, 1, 2])
```

## Custom Interval Data

Often you will want to use different interval data for your simulation - for example modelling site network charges.

Additional keyword arguments passed into a site or asset `__init__` are attempted to be parsed into interval data. These will be parsed into site interval data, even if passed into an asset.

For example, when we pass in a `network_charge` argument, we end up with a `network_charge` attribute on our `asset.site.cfg.interval_data` object:

```python
import energypylinear as epl

electricity_prices = [100, 50, 200]
asset = epl.Battery(electricity_prices=[100, 50, 200], network_charges=[10, 20, 30])
print(asset.site.cfg.interval_data)
```

```
electricity_prices=array([100., 50., 200.]) export_electricity_prices=array([100., 50., 200.]) electricity_carbon_intensities=array([0.1, 0.1, 0.1]) gas_prices=array([20, 20, 20]) electric_load_mwh=array([0, 0, 0]) high_temperature_load_mwh=array([0, 0, 0]) low_temperature_load_mwh=array([0, 0, 0]) low_temperature_generation_mwh=array([0, 0, 0]) idx=array([0, 1, 2]) network_charges=array([10., 20., 30.])
```

## Custom Interval Data in Simulation Results

All custom interval data will appear in the simulation results:

```python
import energypylinear as epl

asset = epl.Battery(electricity_prices=[100, 50, 200], network_charges=[10, 20, 30])
simulation = asset.optimize(verbose=3)
print(simulation.results["site-network_charges"])
```

```
0 10.0
1 20.0
2 30.0
Name: site-network_charges, dtype: float64
```

## Custom Interval Data in Custom Objective Functions

Custom interval data can be used in a custom objective function:

```python
import energypylinear as epl

asset = epl.Battery(electricity_prices=[100, 50, 200], network_charges=[10, 20, 30])
simulation = asset.optimize(
objective={
"terms": [
{
"asset_type": "site",
"variable": "import_power_mwh",
"interval_data": "electricity_prices",
},
{
"asset_type": "site",
"variable": "export_power_mwh",
"interval_data": "electricity_prices",
"coefficient": -1,
},
]
},
verbose=3
)
```
2 changes: 1 addition & 1 deletion docs/docs/how-to/custom-objectives.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ print(simulate(carbon_price=50, seed=42, n=72))
```

```
<energypylinear.SimulationResult feasible:True, rows:72, cols:28>
<energypylinear.SimulationResult feasible:True, rows:72, cols:29>
```

We can validate that our custom objective function is working as expected by running simulations across many carbon prices:
Expand Down
6 changes: 4 additions & 2 deletions docs/docs/how-to/dispatch-site.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Multiple Assets with the Site API

The `epl.Site` allows optimizing many assets at the same time. The site is a list of `energypylinear` asset models, like `epl.Battery` or `epl.RenewableGenerator`.
`energypylinear` can optimize many assets in a single linear program.

Below we give some examples of typical configurations of energy assets using an `epl.Site`.
The `epl.Site` accepts a list of `energypylinear` asset models, like `epl.Battery` or `epl.RenewableGenerator`.

Below are examples of typical configurations of multiple energy assets using a `epl.Site`.

## Fast & Slow Battery

Expand Down
Loading

0 comments on commit 558be05

Please sign in to comment.