-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Matthias Wende <matthias.wende@frequenz.com>
- Loading branch information
1 parent
b71335f
commit eabafd2
Showing
1 changed file
with
73 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Optimizing PV production | ||
|
||
## Introduction | ||
In this tutorial we want to write an application that optimizes the energy produced from a PV system with | ||
Battery for self consumption. | ||
In order to do so we need to measure the power that flows through the grid connection point | ||
(TODO link to glossary) to determine excess power. | ||
|
||
Before we start it's assumed that you have finished the first [tutorial](./getting_started.md) | ||
|
||
## Measure the excess power | ||
|
||
When using the term excess power what we actually mean is the consumer excess power, that is the power that | ||
flows from the PV system into the grid. | ||
|
||
!!! note | ||
|
||
We are using the passive sign convention (TODO link) and thus power flowing from the PV is negative | ||
and consumed power is positive. | ||
|
||
We want to measure the excess power. In order to do so you can use the SDK's data pipeline and especially | ||
the pre defined consumer and producer power formulas (TODO is there a documentation for those?) | ||
|
||
```python | ||
async def run() -> None: | ||
... # (1)! | ||
|
||
# negative means feed-in power due to the negative sign convention | ||
consumer_excess_power_engine = ( | ||
microgrid.logical_meter().producer_power | ||
+ microgrid.logical_meter().consumer_power | ||
).build("excess_power") # (2)! | ||
cons_excess_power_recv = cons_excess_power_engine.new_receiver() # (3)! | ||
``` | ||
|
||
1. The initialization code as explained in the Getting Started tutorial. | ||
2. Construct the consumer excess power by summing up consumer and producer power each of which having | ||
opposite signs due to the sign convention. This returns a formula engine. | ||
3. Request a receiver from the formula engine which will be used to consume the stream. | ||
|
||
## Control the Battery | ||
|
||
Now you can use a battery pool to control the batteries. | ||
Finally you need to combine the data pipeline with the controlling to build the optimization logic. | ||
|
||
|
||
```python | ||
... | ||
|
||
battery_pool = microgrid.battery_pool() # (1)! | ||
|
||
async for cons_excess_power in cons_excess_power_recv: # (2)! | ||
cons_excess_power = cons_excess_power.value # (3)! | ||
if cons_excess_power is None: # (4)! | ||
continue | ||
if cons_excess_power <= Power.zero(): # (5)! | ||
await battery_pool.charge(-cons_excess_power) | ||
elif cons_excess_power > Power.zero(): | ||
await battery_pool.discharge(discharge_power) | ||
|
||
``` | ||
|
||
1. Get an instance of the battery pool. | ||
2. Iterate asynchronously over the constructed consumer excess power stream. | ||
3. Get the `Quantity` from the received `Sample`. | ||
4. Do nothing if we didn't receive new data. | ||
5. | ||
|
||
|
||
## Further reading | ||
|
||
(TODO links) | ||
To create more advanced applications you may want to read the documentation on actors and channels. |