Skip to content

Commit d9faff3

Browse files
committed
Remove dependence on _ComposableFormulaEngine in FormulaEngine3Phase
`_ComposableFormulaEngine` is a generic class exposing arithmetic methods with typing for single-phase and three-phase formulas. But typing support has been incorrect and incomplete since the beginning. The cleanest solution appears to be to just implement the methods on each of the `FormulaEngine`s separately, so that they can be fully typed. Signed-off-by: Sahas Subramanian <[email protected]>
1 parent e2d58f1 commit d9faff3

File tree

1 file changed

+138
-8
lines changed

1 file changed

+138
-8
lines changed

src/frequenz/sdk/timeseries/formula_engine/_formula_engine.py

Lines changed: 138 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -555,13 +555,7 @@ def new_receiver(
555555
return recv
556556

557557

558-
class FormulaEngine3Phase(
559-
_ComposableFormulaEngine[
560-
"FormulaEngine3Phase", # type: ignore[type-arg]
561-
"HigherOrderFormulaBuilder3Phase", # type: ignore[type-arg]
562-
QuantityT,
563-
]
564-
):
558+
class FormulaEngine3Phase(Generic[QuantityT]):
565559
"""A
566560
[`FormulaEngine3Phase`][frequenz.sdk.timeseries.formula_engine.FormulaEngine3Phase]
567561
is similar to a
@@ -632,7 +626,7 @@ def __init__(
632626
"""
633627
self._higher_order_builder = HigherOrderFormulaBuilder3Phase
634628
self._name: str = name
635-
self._create_method = create_method
629+
self._create_method: Callable[[float], QuantityT] = create_method
636630
self._channel: Broadcast[Sample3Phase[QuantityT]] = Broadcast(name=self._name)
637631
self._task: asyncio.Task[None] | None = None
638632
self._streams: tuple[
@@ -641,6 +635,142 @@ def __init__(
641635
FormulaEngine[QuantityT],
642636
] = phase_streams
643637

638+
async def _stop(self) -> None:
639+
"""Stop a running formula engine."""
640+
if self._task is None:
641+
return
642+
await cancel_and_await(self._task)
643+
644+
def __add__(
645+
self,
646+
other: (
647+
FormulaEngine3Phase[QuantityT] | HigherOrderFormulaBuilder3Phase[QuantityT]
648+
),
649+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
650+
"""Return a formula builder that adds (data in) `other` to `self`.
651+
652+
Args:
653+
other: A formula receiver, or a formula builder instance corresponding to a
654+
sub-expression.
655+
656+
Returns:
657+
A formula builder that can take further expressions, or can be built
658+
into a formula engine.
659+
"""
660+
return HigherOrderFormulaBuilder3Phase(self, self._create_method) + other
661+
662+
def __sub__(
663+
self: FormulaEngine3Phase[QuantityT],
664+
other: (
665+
FormulaEngine3Phase[QuantityT] | HigherOrderFormulaBuilder3Phase[QuantityT]
666+
),
667+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
668+
"""Return a formula builder that subtracts (data in) `other` from `self`.
669+
670+
Args:
671+
other: A formula receiver, or a formula builder instance corresponding to a
672+
sub-expression.
673+
674+
Returns:
675+
A formula builder that can take further expressions, or can be built
676+
into a formula engine.
677+
"""
678+
return HigherOrderFormulaBuilder3Phase(self, self._create_method) - other
679+
680+
def __mul__(
681+
self: FormulaEngine3Phase[QuantityT],
682+
other: (
683+
FormulaEngine3Phase[QuantityT] | HigherOrderFormulaBuilder3Phase[QuantityT]
684+
),
685+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
686+
"""Return a formula builder that multiplies (data in) `self` with `other`.
687+
688+
Args:
689+
other: A formula receiver, or a formula builder instance corresponding to a
690+
sub-expression.
691+
692+
Returns:
693+
A formula builder that can take further expressions, or can be built
694+
into a formula engine.
695+
"""
696+
return HigherOrderFormulaBuilder3Phase(self, self._create_method) * other
697+
698+
def __truediv__(
699+
self: FormulaEngine3Phase[QuantityT],
700+
other: (
701+
FormulaEngine3Phase[QuantityT] | HigherOrderFormulaBuilder3Phase[QuantityT]
702+
),
703+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
704+
"""Return a formula builder that divides (data in) `self` by `other`.
705+
706+
Args:
707+
other: A formula receiver, or a formula builder instance corresponding to a
708+
sub-expression.
709+
710+
Returns:
711+
A formula builder that can take further expressions, or can be built
712+
into a formula engine.
713+
"""
714+
return HigherOrderFormulaBuilder3Phase(self, self._create_method) / other
715+
716+
def max(
717+
self: FormulaEngine3Phase[QuantityT],
718+
other: (
719+
FormulaEngine3Phase[QuantityT] | HigherOrderFormulaBuilder3Phase[QuantityT]
720+
),
721+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
722+
"""Return a formula engine that outputs the maximum of `self` and `other`.
723+
724+
Args:
725+
other: A formula receiver, a formula builder or a QuantityT instance
726+
corresponding to a sub-expression.
727+
728+
Returns:
729+
A formula builder that can take further expressions, or can be built
730+
into a formula engine.
731+
"""
732+
return HigherOrderFormulaBuilder3Phase(self, self._create_method).max(other)
733+
734+
def min(
735+
self: FormulaEngine3Phase[QuantityT],
736+
other: (
737+
FormulaEngine3Phase[QuantityT] | HigherOrderFormulaBuilder3Phase[QuantityT]
738+
),
739+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
740+
"""Return a formula engine that outputs the minimum of `self` and `other`.
741+
742+
Args:
743+
other: A formula receiver, a formula builder or a QuantityT instance
744+
corresponding to a sub-expression.
745+
746+
Returns:
747+
A formula builder that can take further expressions, or can be built
748+
into a formula engine.
749+
"""
750+
return HigherOrderFormulaBuilder3Phase(self, self._create_method).min(other)
751+
752+
def consumption(
753+
self: FormulaEngine3Phase[QuantityT],
754+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
755+
"""
756+
Return a formula builder that applies the consumption operator on `self`.
757+
758+
The consumption operator returns either the identity if the power value is
759+
positive or 0.
760+
"""
761+
return HigherOrderFormulaBuilder3Phase(self, self._create_method).consumption()
762+
763+
def production(
764+
self: FormulaEngine3Phase[QuantityT],
765+
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
766+
"""
767+
Return a formula builder that applies the production operator on `self`.
768+
769+
The production operator returns either the absolute value if the power value is
770+
negative or 0.
771+
"""
772+
return HigherOrderFormulaBuilder3Phase(self, self._create_method).production()
773+
644774
async def _run(self) -> None:
645775
sender = self._channel.new_sender()
646776
phase_1_rx = self._streams[0].new_receiver()

0 commit comments

Comments
 (0)