Skip to content

Commit 52a2f78

Browse files
Add logical component for consumer power formulas
Signed-off-by: Daniel Zullo <[email protected]>
1 parent b425905 commit 52a2f78

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# License: MIT
2+
# Copyright © 2022 Frequenz Energy-as-a-Service GmbH
3+
4+
"""The logical component for calculating high level consumer metrics for a microgrid."""
5+
6+
import uuid
7+
8+
from frequenz.channels import Sender
9+
10+
from ..actor import ChannelRegistry, ComponentMetricRequest
11+
from ._quantities import Power
12+
from .formula_engine import FormulaEngine
13+
from .formula_engine._formula_engine_pool import FormulaEnginePool
14+
from .formula_engine._formula_generators import ConsumerPowerFormula
15+
16+
17+
class Consumer:
18+
"""Calculate high level consumer metrics in a microgrid.
19+
20+
Under normal circumstances this is expected to correspond to the gross
21+
consumption of the site excluding active parts and battery.
22+
23+
Consumer provides methods for fetching power values from different points
24+
in the microgrid. These methods return `FormulaReceiver` objects, which can
25+
be used like normal `Receiver`s, but can also be composed to form
26+
higher-order formula streams.
27+
28+
!!! note
29+
`Consumer` instances are not meant to be created directly by users.
30+
Use the [`microgrid.consumer`][frequenz.sdk.microgrid.consumer] method
31+
for creating `Consumer` instances.
32+
33+
Example:
34+
```python
35+
from datetime import timedelta
36+
37+
from frequenz.sdk import microgrid
38+
from frequenz.sdk.timeseries import ResamplerConfig
39+
40+
await microgrid.initialize(
41+
"127.0.0.1",
42+
50051,
43+
ResamplerConfig(resampling_period=timedelta(seconds=1.0))
44+
)
45+
46+
consumer = microgrid.consumer()
47+
48+
# Get a receiver for a builtin formula
49+
consumer_power_recv = consumer.power.new_receiver()
50+
async for consumer_power_sample in consumer_power_recv:
51+
print(consumer_power_sample)
52+
```
53+
"""
54+
55+
_formula_pool: FormulaEnginePool
56+
"""The formula engine pool to generate consumer metrics."""
57+
58+
def __init__(
59+
self,
60+
channel_registry: ChannelRegistry,
61+
resampler_subscription_sender: Sender[ComponentMetricRequest],
62+
) -> None:
63+
"""Initialize the consumer formula generator.
64+
65+
Args:
66+
channel_registry: The channel registry to use for the consumer.
67+
resampler_subscription_sender: The sender to use for resampler subscriptions.
68+
"""
69+
namespace = f"consumer-{uuid.uuid4()}"
70+
self._formula_pool = FormulaEnginePool(
71+
namespace,
72+
channel_registry,
73+
resampler_subscription_sender,
74+
)
75+
76+
@property
77+
def power(self) -> FormulaEngine[Power]:
78+
"""Fetch the consumer power for the microgrid.
79+
80+
This formula produces values that are in the Passive Sign Convention (PSC).
81+
82+
It will start the formula engine to calculate consumer power if it is
83+
not already running.
84+
85+
A receiver from the formula engine can be created using the
86+
`new_receiver` method.
87+
88+
Returns:
89+
A FormulaEngine that will calculate and stream consumer power.
90+
"""
91+
engine = self._formula_pool.from_power_formula_generator(
92+
"consumer_power",
93+
ConsumerPowerFormula,
94+
)
95+
assert isinstance(engine, FormulaEngine)
96+
return engine
97+
98+
async def stop(self) -> None:
99+
"""Stop all formula engines."""
100+
await self._formula_pool.stop()

0 commit comments

Comments
 (0)