Skip to content
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

Battery status with channel communication #171

Conversation

ela-kotulska-frequenz
Copy link
Contributor

No description provided.

@ela-kotulska-frequenz ela-kotulska-frequenz added part:data-pipeline Affects the data pipeline part:power-management Affects the management of battery power and distribution labels Jan 23, 2023
@ela-kotulska-frequenz ela-kotulska-frequenz added this to the v0.17.0 milestone Jan 23, 2023
@ela-kotulska-frequenz ela-kotulska-frequenz self-assigned this Jan 23, 2023
@ela-kotulska-frequenz ela-kotulska-frequenz requested a review from a team as a code owner January 23, 2023 09:38
@github-actions github-actions bot added part:actor Affects an actor ot the actors utilities (decorator, etc.) part:microgrid Affects the interactions with the microgrid part:tests Affects the unit, integration and performance (benchmarks) tests and removed part:data-pipeline Affects the data pipeline part:power-management Affects the management of battery power and distribution labels Jan 23, 2023
@ela-kotulska-frequenz ela-kotulska-frequenz force-pushed the battery_status_impl branch 4 times, most recently from 6bd3146 to 3adb945 Compare January 26, 2023 13:34
@ela-kotulska-frequenz
Copy link
Contributor Author

Unit tests are waiting for: frequenz-floss/frequenz-channels-python#68

Copy link
Contributor

@shsms shsms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've checked the first 4 commits later (and one thing with the big commit).

I'll continue tomorrow.

src/frequenz/sdk/microgrid/_battery/_status.py Outdated Show resolved Hide resolved
src/frequenz/sdk/microgrid/_battery/_status.py Outdated Show resolved Hide resolved
Comment on lines 58 to 61
class _ComponentData(Generic[T]):
component_id: int
receiver: Peekable[T]
last_msg_timestamp: datetime = datetime.now(tz=timezone.utc)
last_msg_correct: bool = False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you can now rename this class to _ComponentStreamStatus? Also it is not generic anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -45,10 +40,25 @@ class BatteryStatus(Enum):
"""Component is working"""


@dataclass
class RequestResult:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to go to microgrid/_battery? I think this is specific to the power distributor.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also rename this to SetPowerResult or something? RequestResult sounds too confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved whole file to frequez.sdk.actor.power_distributing.
Renamed RequestResult to SetPowerResult.

@@ -113,12 +123,10 @@ def is_blocked(self) -> bool:
return self.blocked_until > datetime.now(tz=timezone.utc)


class BatteryStatusTracker(AsyncConstructible):
class BatteryStatusTracker:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This too, I think should sit outside the microgrid package. The microgrid package is supposed to be a thin wrapper providing access to data from the microgrid and for sending commands to the microgrid.

But this class is really stateful tracking logic, which should ideally be part of a higher level package, possibly the actor/power_distributing. I see that this code was already merged, so I can move out later also, if you prefer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to actor/power_distributing

To create an instance of this class you should use `async_new` class method.
Standard constructor (__init__) is not supported and using it will raise
`NotSyncConstructible` error.
Status in send only when it change.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Status in send only when it change.
Status updates are sent out only when there is a status change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

self.sender = channel.new_sender()


class BatteriesStatus:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you're going to rename this to AllBatteryStatus as discussed, and the file accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed to BatteryPoolStatus once again.
Because it has battery_ids as argument, so it can be created for pool, too.
Also BatteryPoolStatus sounds better after all.


self._batteries: Dict[str, BatteryStatusTracker] = {}

# Receivers are needed to create Select object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Receivers are needed to create Select object
# Receivers for individual battery statuses are needed to create a `MergeNamed` object

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

try:
await self._update_status(self._battery_status_channel)
except Exception as err: # pylint: disable=broad-except
_logger.error("BatteriesStatus failed with error: %s. Restart.", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_logger.error("BatteriesStatus failed with error: %s. Restart.", err)
_logger.error("BatteriesStatus failed with error: %s. Restarting.", err)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


Raises:
KeyError: If any battery in the given batteries is not in the pool.
async def _update_status(self, status_channel: MergeNamed[BatteryStatus]) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe more readable to decompose to a Receiver, like below, but it is ok to keep it as it is also.

Suggested change
async def _update_status(self, status_channel: MergeNamed[BatteryStatus]) -> None:
async def _update_status(self, status_channel: Receiver[tuple[str, BatteryStatus]]) -> None:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to leave it MergeNamed.
It is clear and shorter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, why not just use self._battery_status_channel and not pass anything at all?

"""Return status of the battery.
async def stop(self) -> None:
"""Stop tracking battery status."""
if self._select is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should probably also cancel_and_await(self._task) here, before killing the Select.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
And simplify BatteriesStatus code.

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
In the future commit blocking will be only in BatteryStatusTracker.
All blocking related public functions will be removed.

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
Move getting status functionality to separate method.

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
BatteryStatusTracker receives messages from components, parse it.
If status change BatteryStatusTracker sends new status using channel.
BatteriesStatus is now only class that listen for change of
status from any batteries and updates set of working batteries.

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
... and stop MergeNamed object in BatteriesStatus.

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
@github-actions github-actions bot added the part:tooling Affects the development tooling (CI, deployment, dependency management, etc.) label Jan 30, 2023
Move from frequenz/sdk/microgrid/_battery/_status.py to
frequenz/sdk/actor/power_distributing/_battery_status.py

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
Rename from batteries_status.py to battery_pool_status.py

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
... battery_status.py and battery_pool_status.py

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
BatteryStatus will be used outside, by users.
Status is just an internal class.

Signed-off-by: ela-kotulska-frequenz <elzbieta.kotulska@frequenz.com>
@ela-kotulska-frequenz ela-kotulska-frequenz merged commit bf36ba6 into frequenz-floss:v0.x.x Jan 31, 2023
@ela-kotulska-frequenz ela-kotulska-frequenz deleted the battery_status_impl branch March 7, 2023 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
part:actor Affects an actor ot the actors utilities (decorator, etc.) part:microgrid Affects the interactions with the microgrid part:tests Affects the unit, integration and performance (benchmarks) tests part:tooling Affects the development tooling (CI, deployment, dependency management, etc.)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants