Revert powerwall back to awaiting each api call (#110947)

We converted these to run as tasks in the hope that it would be faster,
but since the cost of establishing another connection and the task
overhead exceeded the savings, it makes sense to await them all in
series.
This commit is contained in:
J. Nick Koston 2024-02-19 13:13:49 -06:00 committed by GitHub
parent 058eec114b
commit 1bc0263ea4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,7 +1,6 @@
"""The Tesla Powerwall integration."""
from __future__ import annotations
import asyncio
from contextlib import AsyncExitStack
from datetime import timedelta
import logging
@ -221,35 +220,26 @@ async def _login_and_fetch_base_info(
async def _call_base_info(power_wall: Powerwall, host: str) -> PowerwallBaseInfo:
"""Return PowerwallBaseInfo for the device."""
try:
async with asyncio.TaskGroup() as tg:
gateway_din = tg.create_task(power_wall.get_gateway_din())
site_info = tg.create_task(power_wall.get_site_info())
status = tg.create_task(power_wall.get_status())
device_type = tg.create_task(power_wall.get_device_type())
serial_numbers = tg.create_task(power_wall.get_serial_numbers())
batteries = tg.create_task(power_wall.get_batteries())
# Mimic the behavior of asyncio.gather by reraising the first caught exception since
# this is what is expected by the caller of this method
#
# While it would have been cleaner to use asyncio.gather in the first place instead of
# TaskGroup but in cases where you have more than 6 tasks, the linter fails due to
# missing typing information.
except BaseExceptionGroup as e:
raise e.exceptions[0] from None
# We await each call individually since the powerwall
# supports http keep-alive and we want to reuse the connection
# as its faster than establishing a new connection when
# run concurrently.
gateway_din = await power_wall.get_gateway_din()
site_info = await power_wall.get_site_info()
status = await power_wall.get_status()
device_type = await power_wall.get_device_type()
serial_numbers = await power_wall.get_serial_numbers()
batteries = await power_wall.get_batteries()
# Serial numbers MUST be sorted to ensure the unique_id is always the same
# for backwards compatibility.
return PowerwallBaseInfo(
gateway_din=gateway_din.result().upper(),
site_info=site_info.result(),
status=status.result(),
device_type=device_type.result(),
serial_numbers=sorted(serial_numbers.result()),
gateway_din=gateway_din,
site_info=site_info,
status=status,
device_type=device_type,
serial_numbers=sorted(serial_numbers),
url=f"https://{host}",
batteries={battery.serial_number: battery for battery in batteries.result()},
batteries={battery.serial_number: battery for battery in batteries},
)
@ -263,34 +253,25 @@ async def get_backup_reserve_percentage(power_wall: Powerwall) -> Optional[float
async def _fetch_powerwall_data(power_wall: Powerwall) -> PowerwallData:
"""Process and update powerwall data."""
try:
async with asyncio.TaskGroup() as tg:
backup_reserve = tg.create_task(get_backup_reserve_percentage(power_wall))
charge = tg.create_task(power_wall.get_charge())
site_master = tg.create_task(power_wall.get_sitemaster())
meters = tg.create_task(power_wall.get_meters())
grid_services_active = tg.create_task(power_wall.is_grid_services_active())
grid_status = tg.create_task(power_wall.get_grid_status())
batteries = tg.create_task(power_wall.get_batteries())
# Mimic the behavior of asyncio.gather by reraising the first caught exception since
# this is what is expected by the caller of this method
#
# While it would have been cleaner to use asyncio.gather in the first place instead of
# TaskGroup but in cases where you have more than 6 tasks, the linter fails due to
# missing typing information.
except BaseExceptionGroup as e:
raise e.exceptions[0] from None
# We await each call individually since the powerwall
# supports http keep-alive and we want to reuse the connection
# as its faster than establishing a new connection when
# run concurrently.
backup_reserve = await get_backup_reserve_percentage(power_wall)
charge = await power_wall.get_charge()
site_master = await power_wall.get_sitemaster()
meters = await power_wall.get_meters()
grid_services_active = await power_wall.is_grid_services_active()
grid_status = await power_wall.get_grid_status()
batteries = await power_wall.get_batteries()
return PowerwallData(
charge=charge.result(),
site_master=site_master.result(),
meters=meters.result(),
grid_services_active=grid_services_active.result(),
grid_status=grid_status.result(),
backup_reserve=backup_reserve.result(),
batteries={battery.serial_number: battery for battery in batteries.result()},
charge=charge,
site_master=site_master,
meters=meters,
grid_services_active=grid_services_active,
grid_status=grid_status,
backup_reserve=backup_reserve,
batteries={battery.serial_number: battery for battery in batteries},
)