Leave Powerwall gateway host blank when discovery fails (#181336)

This commit is contained in:
Brett Adams
2026-09-05 08:30:15 +02:00
committed by GitHub
parent e1efb35a97
commit e37a8cfa98
2 changed files with 44 additions and 12 deletions
@@ -6,12 +6,7 @@ from pathlib import Path
from typing import TYPE_CHECKING, Any, cast, override
from aiohttp import ClientError
from aiopowerwall import (
DEFAULT_GATEWAY_HOST,
PowerwallAuthenticationError,
PowerwallClient,
PowerwallError,
)
from aiopowerwall import PowerwallAuthenticationError, PowerwallClient, PowerwallError
from tesla_fleet_api.const import (
AuthorizedClientKeyType,
AuthorizedClientState,
@@ -271,8 +266,11 @@ class EnergySiteSubentryFlowHandler(ConfigSubentryFlow):
try:
self._discovered_host = await energy_site.find_gateway_address() or ""
except (ClientError, TeslaFleetError) as err:
LOGGER.debug("Gateway address discovery failed: %s", err)
LOGGER.warning("Gateway address discovery failed: %s", err)
self._discovered_host = ""
else:
if not self._discovered_host:
LOGGER.warning("Gateway address discovery returned no address")
path = self.hass.config.path(POWERWALL_KEY_FILE)
keyholder = Teslemetry(
@@ -424,7 +422,7 @@ class EnergySiteSubentryFlowHandler(ConfigSubentryFlow):
{
vol.Required(
CONF_HOST,
default=self._discovered_host or DEFAULT_GATEWAY_HOST,
default=self._discovered_host or vol.UNDEFINED,
): str,
vol.Required(CONF_PASSWORD): str,
}
@@ -9,7 +9,6 @@ from urllib.parse import parse_qs, urlparse
from aiohttp import ClientConnectionError, ClientError
from aiopowerwall import (
DEFAULT_GATEWAY_HOST,
PowerwallAuthenticationError,
PowerwallConnectionError,
PowerwallFaultError,
@@ -25,6 +24,7 @@ from tesla_fleet_api.exceptions import (
TeslaFleetError,
)
from tesla_fleet_api.teslemetry.energysite import AuthorizedClient, AuthorizedClients
import voluptuous as vol
from homeassistant.components.application_credentials import (
ClientCredential,
@@ -838,6 +838,14 @@ def _credentials_host_default(result: SubentryFlowResult) -> str:
raise AssertionError("CONF_HOST field not found in credentials schema")
def _credentials_host_is_blank(result: SubentryFlowResult) -> bool:
"""Return whether the CONF_HOST field carries no schema default (left blank)."""
for key in result["data_schema"].schema:
if key == CONF_HOST:
return key.default is vol.UNDEFINED
raise AssertionError("CONF_HOST field not found in credentials schema")
@pytest.mark.usefixtures("mock_rsa_key")
async def test_energy_subentry_pairing_requires_key_approval(
hass: HomeAssistant,
@@ -1249,10 +1257,10 @@ async def test_add_flow_aborts_when_entry_not_loaded(hass: HomeAssistant) -> Non
@pytest.mark.usefixtures("mock_rsa_key")
async def test_gateway_discovery_failure_proceeds_without_host(
async def test_gateway_discovery_failure_leaves_host_blank(
hass: HomeAssistant,
) -> None:
"""A failed gateway-address discovery leaves the host default unset."""
"""A failed gateway-address discovery leaves the host field blank and proceeds."""
entry = await _setup_account_no_subentry(hass)
with (
@@ -1271,7 +1279,33 @@ async def test_gateway_discovery_failure_proceeds_without_host(
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "credentials"
assert _credentials_host_default(result) == DEFAULT_GATEWAY_HOST
assert _credentials_host_is_blank(result)
@pytest.mark.usefixtures("mock_rsa_key")
async def test_gateway_discovery_empty_leaves_host_blank(
hass: HomeAssistant,
) -> None:
"""Discovery returning no address (without raising) leaves the host blank and proceeds."""
entry = await _setup_account_no_subentry(hass)
with (
patch(
"tesla_fleet_api.teslemetry.energysite.TeslemetryEnergySite.find_gateway_address",
new=AsyncMock(return_value=None),
),
patch(
"tesla_fleet_api.teslemetry.energysite.TeslemetryEnergySite.find_authorized_clients",
new=AsyncMock(
return_value=_own_key_clients(AuthorizedClientState.VERIFIED)
),
),
):
result = await _start_add_flow_select_site(hass, entry)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "credentials"
assert _credentials_host_is_blank(result)
@pytest.mark.usefixtures("mock_rsa_key")