Fix wallbox jwt issue (#79948)

* Bump Wallbox package

* remove debug message

* Force update of auth token by emptying it first

* Force token refresh by emptying token
Improve exception handling

* include tests

* Update __init__.py

* Removed the clearing ot jwt token, issue is fixed by upstream fix in wallbox package.

* Catch connectionerror

* Update homeassistant/components/wallbox/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Run black

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
hesselonline 2022-10-14 13:09:00 +02:00 committed by GitHub
parent 8dc3ff72c6
commit a534c136a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 8 deletions

View File

@ -17,6 +17,7 @@ from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import ( from homeassistant.helpers.update_coordinator import (
CoordinatorEntity, CoordinatorEntity,
DataUpdateCoordinator, DataUpdateCoordinator,
UpdateFailed,
) )
from .const import ( from .const import (
@ -93,6 +94,7 @@ class WallboxCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""Authenticate using Wallbox API.""" """Authenticate using Wallbox API."""
try: try:
self._wallbox.authenticate() self._wallbox.authenticate()
except requests.exceptions.HTTPError as wallbox_connection_error: except requests.exceptions.HTTPError as wallbox_connection_error:
if wallbox_connection_error.response.status_code == HTTPStatus.FORBIDDEN: if wallbox_connection_error.response.status_code == HTTPStatus.FORBIDDEN:
raise ConfigEntryAuthFailed from wallbox_connection_error raise ConfigEntryAuthFailed from wallbox_connection_error
@ -125,11 +127,12 @@ class WallboxCoordinator(DataUpdateCoordinator[dict[str, Any]]):
data[CHARGER_STATUS_DESCRIPTION_KEY] = CHARGER_STATUS.get( data[CHARGER_STATUS_DESCRIPTION_KEY] = CHARGER_STATUS.get(
data[CHARGER_STATUS_ID_KEY], ChargerStatus.UNKNOWN data[CHARGER_STATUS_ID_KEY], ChargerStatus.UNKNOWN
) )
return data return data
except (
except requests.exceptions.HTTPError as wallbox_connection_error: ConnectionError,
raise ConnectionError from wallbox_connection_error requests.exceptions.HTTPError,
) as wallbox_connection_error:
raise UpdateFailed from wallbox_connection_error
async def _async_update_data(self) -> dict[str, Any]: async def _async_update_data(self) -> dict[str, Any]:
"""Get new sensor data for Wallbox component.""" """Get new sensor data for Wallbox component."""

View File

@ -6,6 +6,7 @@ from typing import Any
from homeassistant.components.lock import LockEntity, LockEntityDescription from homeassistant.components.lock import LockEntity, LockEntityDescription
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import InvalidAuth, WallboxCoordinator, WallboxEntity from . import InvalidAuth, WallboxCoordinator, WallboxEntity
@ -36,6 +37,8 @@ async def async_setup_entry(
) )
except InvalidAuth: except InvalidAuth:
return return
except ConnectionError as exc:
raise PlatformNotReady from exc
async_add_entities( async_add_entities(
[ [

View File

@ -3,7 +3,7 @@
"name": "Wallbox", "name": "Wallbox",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/wallbox", "documentation": "https://www.home-assistant.io/integrations/wallbox",
"requirements": ["wallbox==0.4.9"], "requirements": ["wallbox==0.4.10"],
"codeowners": ["@hesselonline"], "codeowners": ["@hesselonline"],
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"loggers": ["wallbox"] "loggers": ["wallbox"]

View File

@ -7,6 +7,7 @@ from typing import Optional, cast
from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.components.number import NumberEntity, NumberEntityDescription
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import InvalidAuth, WallboxCoordinator, WallboxEntity from . import InvalidAuth, WallboxCoordinator, WallboxEntity
@ -46,6 +47,8 @@ async def async_setup_entry(
) )
except InvalidAuth: except InvalidAuth:
return return
except ConnectionError as exc:
raise PlatformNotReady from exc
async_add_entities( async_add_entities(
[ [

View File

@ -2512,7 +2512,7 @@ vultr==0.1.2
wakeonlan==2.1.0 wakeonlan==2.1.0
# homeassistant.components.wallbox # homeassistant.components.wallbox
wallbox==0.4.9 wallbox==0.4.10
# homeassistant.components.waqi # homeassistant.components.waqi
waqiasync==1.0.0 waqiasync==1.0.0

View File

@ -1740,7 +1740,7 @@ vultr==0.1.2
wakeonlan==2.1.0 wakeonlan==2.1.0
# homeassistant.components.wallbox # homeassistant.components.wallbox
wallbox==0.4.9 wallbox==0.4.10
# homeassistant.components.folder_watcher # homeassistant.components.folder_watcher
watchdog==2.1.9 watchdog==2.1.9

View File

@ -173,3 +173,29 @@ async def setup_integration_read_only(hass: HomeAssistant) -> None:
await hass.config_entries.async_setup(entry.entry_id) await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
async def setup_integration_platform_not_ready(hass: HomeAssistant) -> None:
"""Test wallbox sensor class setup for read only."""
with requests_mock.Mocker() as mock_request:
mock_request.get(
"https://user-api.wall-box.com/users/signin",
json=authorisation_response,
status_code=HTTPStatus.OK,
)
mock_request.get(
"https://api.wall-box.com/chargers/status/12345",
json=test_response,
status_code=HTTPStatus.OK,
)
mock_request.put(
"https://api.wall-box.com/v2/charger/12345",
json=test_response,
status_code=HTTPStatus.NOT_FOUND,
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

View File

@ -13,6 +13,7 @@ from . import (
authorisation_response, authorisation_response,
entry, entry,
setup_integration, setup_integration,
setup_integration_platform_not_ready,
setup_integration_read_only, setup_integration_read_only,
) )
from .const import MOCK_LOCK_ENTITY_ID from .const import MOCK_LOCK_ENTITY_ID
@ -109,3 +110,15 @@ async def test_wallbox_lock_class_authentication_error(hass: HomeAssistant) -> N
assert state is None assert state is None
await hass.config_entries.async_unload(entry.entry_id) await hass.config_entries.async_unload(entry.entry_id)
async def test_wallbox_lock_class_platform_not_ready(hass: HomeAssistant) -> None:
"""Test wallbox lock not loaded on authentication error."""
await setup_integration_platform_not_ready(hass)
state = hass.states.get(MOCK_LOCK_ENTITY_ID)
assert state is None
await hass.config_entries.async_unload(entry.entry_id)

View File

@ -9,7 +9,12 @@ from homeassistant.components.wallbox import CHARGER_MAX_CHARGING_CURRENT_KEY
from homeassistant.const import ATTR_ENTITY_ID from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from . import authorisation_response, entry, setup_integration from . import (
authorisation_response,
entry,
setup_integration,
setup_integration_platform_not_ready,
)
from .const import MOCK_NUMBER_ENTITY_ID from .const import MOCK_NUMBER_ENTITY_ID
@ -71,3 +76,15 @@ async def test_wallbox_number_class_connection_error(hass: HomeAssistant) -> Non
blocking=True, blocking=True,
) )
await hass.config_entries.async_unload(entry.entry_id) await hass.config_entries.async_unload(entry.entry_id)
async def test_wallbox_number_class_platform_not_ready(hass: HomeAssistant) -> None:
"""Test wallbox lock not loaded on authentication error."""
await setup_integration_platform_not_ready(hass)
state = hass.states.get(MOCK_NUMBER_ENTITY_ID)
assert state is None
await hass.config_entries.async_unload(entry.entry_id)