Skip to content

Commit

Permalink
Address ruckus_unleashed late review (#99411)
Browse files Browse the repository at this point in the history
  • Loading branch information
ms264556 committed Sep 10, 2023
1 parent 7acc606 commit 3b25262
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 96 deletions.
4 changes: 2 additions & 2 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -1064,8 +1064,8 @@ build.json @home-assistant/supervisor
/tests/components/rss_feed_template/ @home-assistant/core
/homeassistant/components/rtsp_to_webrtc/ @allenporter
/tests/components/rtsp_to_webrtc/ @allenporter
/homeassistant/components/ruckus_unleashed/ @gabe565 @lanrat
/tests/components/ruckus_unleashed/ @gabe565 @lanrat
/homeassistant/components/ruckus_unleashed/ @lanrat @ms264556 @gabe565
/tests/components/ruckus_unleashed/ @lanrat @ms264556 @gabe565
/homeassistant/components/ruuvi_gateway/ @akx
/tests/components/ruuvi_gateway/ @akx
/homeassistant/components/ruuvitag_ble/ @akx
Expand Down
18 changes: 10 additions & 8 deletions homeassistant/components/ruckus_unleashed/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging

from aioruckus import AjaxSession
from aioruckus.exceptions import AuthenticationError
from aioruckus.exceptions import AuthenticationError, SchemaError

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
Expand Down Expand Up @@ -31,16 +31,18 @@
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Ruckus Unleashed from a config entry."""

ruckus = AjaxSession.async_create(
entry.data[CONF_HOST],
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
)
try:
ruckus = AjaxSession.async_create(
entry.data[CONF_HOST],
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
)
await ruckus.login()
except (ConnectionRefusedError, ConnectionError) as conerr:
except (ConnectionError, SchemaError) as conerr:
await ruckus.close()
raise ConfigEntryNotReady from conerr
except AuthenticationError as autherr:
await ruckus.close()
raise ConfigEntryAuthFailed from autherr

coordinator = RuckusUnleashedDataUpdateCoordinator(hass, ruckus=ruckus)
Expand Down Expand Up @@ -84,7 +86,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if unload_ok:
for listener in hass.data[DOMAIN][entry.entry_id][UNDO_UPDATE_LISTENERS]:
listener()
await hass.data[DOMAIN][entry.entry_id][COORDINATOR].ruckus.close()
await hass.data[DOMAIN][entry.entry_id][COORDINATOR].ruckus.close()
hass.data[DOMAIN].pop(entry.entry_id)

return unload_ok
74 changes: 45 additions & 29 deletions homeassistant/components/ruckus_unleashed/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Config flow for Ruckus Unleashed integration."""
from collections.abc import Mapping
import logging
from typing import Any

from aioruckus import AjaxSession, SystemStat
from aioruckus.exceptions import AuthenticationError
from aioruckus.exceptions import AuthenticationError, SchemaError
import voluptuous as vol

from homeassistant import config_entries, core, exceptions
Expand All @@ -19,6 +20,8 @@
KEY_SYS_TITLE,
)

_LOGGER = logging.getLogger(__package__)

DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): str,
Expand All @@ -38,26 +41,29 @@ async def validate_input(hass: core.HomeAssistant, data):
async with AjaxSession.async_create(
data[CONF_HOST], data[CONF_USERNAME], data[CONF_PASSWORD]
) as ruckus:
system_info = await ruckus.api.get_system_info(
SystemStat.SYSINFO,
)
mesh_name = (await ruckus.api.get_mesh_info())[API_MESH_NAME]
zd_serial = system_info[API_SYS_SYSINFO][API_SYS_SYSINFO_SERIAL]
return {
KEY_SYS_TITLE: mesh_name,
KEY_SYS_SERIAL: zd_serial,
}
mesh_info = await ruckus.api.get_mesh_info()
system_info = await ruckus.api.get_system_info(SystemStat.SYSINFO)
except AuthenticationError as autherr:
raise InvalidAuth from autherr
except (ConnectionRefusedError, ConnectionError, KeyError) as connerr:
except (ConnectionError, SchemaError) as connerr:
raise CannotConnect from connerr

mesh_name = mesh_info[API_MESH_NAME]
zd_serial = system_info[API_SYS_SYSINFO][API_SYS_SYSINFO_SERIAL]

return {
KEY_SYS_TITLE: mesh_name,
KEY_SYS_SERIAL: zd_serial,
}


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Ruckus Unleashed."""

VERSION = 1

_reauth_entry: config_entries.ConfigEntry | None = None

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
Expand All @@ -70,30 +76,40 @@ async def async_step_user(
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
await self.async_set_unique_id(info[KEY_SYS_SERIAL])
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=info[KEY_SYS_TITLE], data=user_input
)

if self._reauth_entry is None:
await self.async_set_unique_id(info[KEY_SYS_SERIAL])
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=info[KEY_SYS_TITLE], data=user_input
)
if info[KEY_SYS_SERIAL] == self._reauth_entry.unique_id:
self.hass.config_entries.async_update_entry(
self._reauth_entry, data=user_input
)
self.hass.async_create_task(
self.hass.config_entries.async_reload(
self._reauth_entry.entry_id
)
)
return self.async_abort(reason="reauth_successful")
errors["base"] = "invalid_host"

data_schema = self.add_suggested_values_to_schema(
DATA_SCHEMA, self._reauth_entry.data if self._reauth_entry else {}
)
return self.async_show_form(
step_id="user", data_schema=DATA_SCHEMA, errors=errors
step_id="user", data_schema=data_schema, errors=errors
)

async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult:
"""Perform reauth upon an API authentication error."""
return await self.async_step_reauth_confirm()

async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Dialog that informs the user that reauth is required."""
if user_input is None:
return self.async_show_form(
step_id="reauth_confirm",
data_schema=DATA_SCHEMA,
)
self._reauth_entry = self.hass.config_entries.async_get_entry(
self.context["entry_id"]
)
return await self.async_step_user()


Expand Down
7 changes: 4 additions & 3 deletions homeassistant/components/ruckus_unleashed/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import logging

from aioruckus import AjaxSession
from aioruckus.exceptions import AuthenticationError
from aioruckus.exceptions import AuthenticationError, SchemaError

from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .const import API_CLIENT_MAC, DOMAIN, KEY_SYS_CLIENTS, SCAN_INTERVAL
Expand Down Expand Up @@ -40,6 +41,6 @@ async def _async_update_data(self) -> dict:
try:
return {KEY_SYS_CLIENTS: await self._fetch_clients()}
except AuthenticationError as autherror:
raise UpdateFailed(autherror) from autherror
except (ConnectionRefusedError, ConnectionError) as conerr:
raise ConfigEntryAuthFailed(autherror) from autherror
except (ConnectionError, SchemaError) as conerr:
raise UpdateFailed(conerr) from conerr
18 changes: 7 additions & 11 deletions homeassistant/components/ruckus_unleashed/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,16 @@ def mac_address(self) -> str:
@property
def name(self) -> str:
"""Return the name."""
return (
self._name
if not self.is_connected
else self.coordinator.data[KEY_SYS_CLIENTS][self._mac][API_CLIENT_HOSTNAME]
)
if not self.is_connected:
return self._name
return self.coordinator.data[KEY_SYS_CLIENTS][self._mac][API_CLIENT_HOSTNAME]

@property
def ip_address(self) -> str:
def ip_address(self) -> str | None:
"""Return the ip address."""
return (
self.coordinator.data[KEY_SYS_CLIENTS][self._mac][API_CLIENT_IP]
if self.is_connected
else None
)
if not self.is_connected:
return None
return self.coordinator.data[KEY_SYS_CLIENTS][self._mac][API_CLIENT_IP]

@property
def is_connected(self) -> bool:
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/ruckus_unleashed/manifest.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"domain": "ruckus_unleashed",
"name": "Ruckus Unleashed",
"codeowners": ["@gabe565", "@lanrat"],
"codeowners": ["@lanrat", "@ms264556", "@gabe565"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/ruckus_unleashed",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["aioruckus", "xmltodict"],
"requirements": ["aioruckus==0.31", "xmltodict==0.13.0"]
"requirements": ["aioruckus==0.34"]
}
4 changes: 3 additions & 1 deletion homeassistant/components/ruckus_unleashed/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"invalid_host": "[%key:common::config_flow::error::invalid_host%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
}
}
3 changes: 1 addition & 2 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ aiorecollect==2023.09.0
aioridwell==2023.07.0

# homeassistant.components.ruckus_unleashed
aioruckus==0.31
aioruckus==0.34

# homeassistant.components.ruuvi_gateway
aioruuvigateway==0.1.0
Expand Down Expand Up @@ -2723,7 +2723,6 @@ xknxproject==3.2.0
# homeassistant.components.bluesound
# homeassistant.components.fritz
# homeassistant.components.rest
# homeassistant.components.ruckus_unleashed
# homeassistant.components.startca
# homeassistant.components.ted5000
# homeassistant.components.zestimate
Expand Down
3 changes: 1 addition & 2 deletions requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ aiorecollect==2023.09.0
aioridwell==2023.07.0

# homeassistant.components.ruckus_unleashed
aioruckus==0.31
aioruckus==0.34

# homeassistant.components.ruuvi_gateway
aioruuvigateway==0.1.0
Expand Down Expand Up @@ -2011,7 +2011,6 @@ xknxproject==3.2.0
# homeassistant.components.bluesound
# homeassistant.components.fritz
# homeassistant.components.rest
# homeassistant.components.ruckus_unleashed
# homeassistant.components.startca
# homeassistant.components.ted5000
# homeassistant.components.zestimate
Expand Down

0 comments on commit 3b25262

Please sign in to comment.