-
Notifications
You must be signed in to change notification settings - Fork 22
Update generated formulas to follow the new naming scheme #350
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
Merged
shsms
merged 14 commits into
frequenz-floss:v0.x.x
from
sahas-subramanian-frequenz:new-power-formulas
May 15, 2023
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
ab1de11
Replace type:ignores with type asserts in formula generation methods
shsms 4a5e11e
Remove unused logger variable from `_logical_meter.py`
shsms 9970163
Add formula step for applying constant values
shsms afbffed
Add a `Clipper` formula step for clipping formula output to a range
shsms c8fb3d7
Add a `FormulaType` parameter for `FormulaGeneratorConfig`
shsms 53efded
Add `grid_{production,consumption}_power` formulas to `LogicalMeter`
shsms eb2bfb6
Add `LogicalMeter.chp_{,consumption,production}power` methods
shsms db77b3c
Add `BatteryPool.{production,consumption}_power` methods
shsms ae084f9
Add `EVChargerPool.{production,consumption}_power` methods
shsms c198ad7
Add component graph methods to check component types
shsms 26eea48
Add formula generator for consumer power
shsms b70d414
Add `LogicalMeter.pv_{production,consumption}_power` methods
shsms ec3b974
Remove redundant test from logical meter
shsms d3d6b31
Add formula power/current sign convention details to docstrings
shsms File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -30,7 +30,7 @@ | |
| import networkx as nx | ||
|
|
||
| from .client import Connection, MicrogridApiClient | ||
| from .component import Component, ComponentCategory | ||
| from .component import Component, ComponentCategory, InverterType | ||
|
|
||
| _logger = logging.getLogger(__name__) | ||
|
|
||
|
|
@@ -113,6 +113,159 @@ def successors(self, component_id: int) -> Set[Component]: | |
| KeyError: if the specified `component_id` is not in the graph | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_pv_inverter(self, component: Component) -> bool: | ||
| """Check if the specified component is a PV inverter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a PV inverter. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_pv_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is a PV meter. | ||
|
|
||
| This is done by checking if the component has only PV inverters as its | ||
| successors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a PV meter. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_pv_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of a PV chain. | ||
|
|
||
| A component is part of a PV chain if it is a PV meter or a PV inverter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of a PV chain. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_battery_inverter(self, component: Component) -> bool: | ||
| """Check if the specified component is a battery inverter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a battery inverter. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_battery_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is a battery meter. | ||
|
|
||
| This is done by checking if the component has only battery inverters as its | ||
| predecessors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a battery meter. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_battery_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of a battery chain. | ||
|
|
||
| A component is part of a battery chain if it is a battery meter or a battery | ||
| inverter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of a battery chain. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_ev_charger(self, component: Component) -> bool: | ||
| """Check if the specified component is an EV charger. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is an EV charger. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_ev_charger_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is an EV charger meter. | ||
|
|
||
| This is done by checking if the component has only EV chargers as its | ||
| successors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is an EV charger meter. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_ev_charger_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of an EV charger chain. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
|
|
||
| A component is part of an EV charger chain if it is an EV charger meter or an | ||
| EV charger. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of an EV charger chain. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_chp(self, component: Component) -> bool: | ||
| """Check if the specified component is a CHP. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a CHP. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_chp_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is a CHP meter. | ||
|
|
||
| This is done by checking if the component has only CHPs as its successors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a CHP meter. | ||
| """ | ||
|
|
||
| @abstractmethod | ||
| def is_chp_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of a CHP chain. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
|
|
||
| A component is part of a CHP chain if it is a CHP meter or a CHP. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of a CHP chain. | ||
| """ | ||
|
|
||
|
|
||
| class _MicrogridComponentGraph(ComponentGraph): | ||
| """ComponentGraph implementation designed to work with the microgrid API. | ||
|
|
@@ -352,6 +505,190 @@ def validate(self) -> None: | |
| self._validate_junctions() | ||
| self._validate_leaf_components() | ||
|
|
||
| def is_pv_inverter(self, component: Component) -> bool: | ||
| """Check if the specified component is a PV inverter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a PV inverter. | ||
| """ | ||
| return ( | ||
| component.category == ComponentCategory.INVERTER | ||
| and component.type == InverterType.SOLAR | ||
| ) | ||
|
|
||
| def is_pv_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is a PV meter. | ||
|
|
||
| This is done by checking if the component has only PV inverters as its | ||
| successors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a PV meter. | ||
| """ | ||
| successors = self.successors(component.component_id) | ||
| return ( | ||
| component.category == ComponentCategory.METER | ||
| and len(successors) > 0 | ||
| and all( | ||
| self.is_pv_inverter(successor) | ||
| for successor in self.successors(component.component_id) | ||
| ) | ||
| ) | ||
|
|
||
| def is_pv_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of a PV chain. | ||
|
|
||
| A component is part of a PV chain if it is either a PV inverter or a PV | ||
| meter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of a PV chain. | ||
| """ | ||
| return self.is_pv_inverter(component) or self.is_pv_meter(component) | ||
|
|
||
| def is_ev_charger(self, component: Component) -> bool: | ||
| """Check if the specified component is an EV charger. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is an EV charger. | ||
| """ | ||
| return component.category == ComponentCategory.EV_CHARGER | ||
|
|
||
| def is_ev_charger_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is an EV charger meter. | ||
|
|
||
| This is done by checking if the component has only EV chargers as its | ||
| successors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is an EV charger meter. | ||
| """ | ||
| successors = self.successors(component.component_id) | ||
| return ( | ||
| component.category == ComponentCategory.METER | ||
| and len(successors) > 0 | ||
| and all(self.is_ev_charger(successor) for successor in successors) | ||
| ) | ||
|
|
||
| def is_ev_charger_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of an EV charger chain. | ||
|
|
||
| A component is part of an EV charger chain if it is either an EV charger or an | ||
| EV charger meter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of an EV charger chain. | ||
| """ | ||
| return self.is_ev_charger(component) or self.is_ev_charger_meter(component) | ||
|
|
||
| def is_battery_inverter(self, component: Component) -> bool: | ||
| """Check if the specified component is a battery inverter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a battery inverter. | ||
| """ | ||
| return ( | ||
| component.category == ComponentCategory.INVERTER | ||
| and component.type == InverterType.BATTERY | ||
| ) | ||
|
|
||
| def is_battery_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is a battery meter. | ||
|
|
||
| This is done by checking if the component has only battery inverters as | ||
| its successors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a battery meter. | ||
| """ | ||
| successors = self.successors(component.component_id) | ||
| return ( | ||
| component.category == ComponentCategory.METER | ||
| and len(successors) > 0 | ||
| and all(self.is_battery_inverter(successor) for successor in successors) | ||
| ) | ||
|
|
||
| def is_battery_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of a battery chain. | ||
|
|
||
| A component is part of a battery chain if it is either a battery inverter or a | ||
| battery meter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of a battery chain. | ||
| """ | ||
| return self.is_battery_inverter(component) or self.is_battery_meter(component) | ||
|
|
||
| def is_chp(self, component: Component) -> bool: | ||
| """Check if the specified component is a CHP. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a CHP. | ||
| """ | ||
| return component.category == ComponentCategory.CHP | ||
|
|
||
| def is_chp_meter(self, component: Component) -> bool: | ||
| """Check if the specified component is a CHP meter. | ||
|
|
||
| This is done by checking if the component has only CHPs as its | ||
| successors. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is a CHP meter. | ||
| """ | ||
| successors = self.successors(component.component_id) | ||
| return ( | ||
| component.category == ComponentCategory.METER | ||
| and len(successors) > 0 | ||
|
sahas-subramanian-frequenz marked this conversation as resolved.
|
||
| and all(self.is_chp(successor) for successor in successors) | ||
| ) | ||
|
|
||
| def is_chp_chain(self, component: Component) -> bool: | ||
| """Check if the specified component is part of a CHP chain. | ||
|
|
||
| A component is part of a CHP chain if it is either a CHP or a CHP meter. | ||
|
|
||
| Args: | ||
| component: component to check. | ||
|
|
||
| Returns: | ||
| Whether the specified component is part of a CHP chain. | ||
| """ | ||
| return self.is_chp(component) or self.is_chp_meter(component) | ||
|
|
||
| def _validate_graph(self) -> None: | ||
| """Check that the underlying graph data is valid. | ||
|
|
||
|
|
||
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to use the docs to define what a battery chain is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done