Skip to content

Commit

Permalink
Merge branch 'dev' into add-more-prometheus-labels
Browse files Browse the repository at this point in the history
  • Loading branch information
jzucker2 authored Oct 3, 2024
2 parents 9e86c50 + 1dd5937 commit 55e7b1c
Show file tree
Hide file tree
Showing 38 changed files with 414 additions and 732 deletions.
2 changes: 0 additions & 2 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -1384,8 +1384,6 @@ build.json @home-assistant/supervisor
/tests/components/spaceapi/ @fabaff
/homeassistant/components/speedtestdotnet/ @rohankapoorcom @engrbm87
/tests/components/speedtestdotnet/ @rohankapoorcom @engrbm87
/homeassistant/components/spider/ @peternijssen
/tests/components/spider/ @peternijssen
/homeassistant/components/splunk/ @Bre77
/homeassistant/components/spotify/ @frenck @joostlek
/tests/components/spotify/ @frenck @joostlek
Expand Down
20 changes: 8 additions & 12 deletions homeassistant/components/elmax/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import voluptuous as vol

from homeassistant.components.zeroconf import ZeroconfServiceInfo
from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.exceptions import HomeAssistantError

from .common import (
Expand Down Expand Up @@ -114,7 +114,6 @@ class ElmaxConfigFlow(ConfigFlow, domain=DOMAIN):
# Panel selection variables
_panels_schema: vol.Schema
_panel_names: dict
_entry: ConfigEntry | None

async def async_step_user(
self, user_input: dict[str, Any] | None = None
Expand Down Expand Up @@ -395,7 +394,6 @@ async def async_step_reauth(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Perform reauth upon an API authentication error."""
self._entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
self._reauth_cloud_username = entry_data.get(CONF_ELMAX_USERNAME)
self._reauth_cloud_panelid = entry_data.get(CONF_ELMAX_PANEL_ID)
return await self.async_step_reauth_confirm()
Expand All @@ -413,22 +411,22 @@ async def async_step_reauth_confirm(

# Handle authentication, make sure the panel we are re-authenticating against is listed among results
# and verify its pin is correct.
assert self._entry is not None
reauth_entry = self._get_reauth_entry()
try:
# Test login.
client = await self._async_login(username=username, password=password)
# Make sure the panel we are authenticating to is still available.
panels = [
p
for p in await client.list_control_panels()
if p.hash == self._entry.data[CONF_ELMAX_PANEL_ID]
if p.hash == reauth_entry.data[CONF_ELMAX_PANEL_ID]
]
if len(panels) < 1:
raise NoOnlinePanelsError # noqa: TRY301

# Verify the pin is still valid.
await client.get_panel_status(
control_panel_id=self._entry.data[CONF_ELMAX_PANEL_ID],
control_panel_id=reauth_entry.data[CONF_ELMAX_PANEL_ID],
pin=panel_pin,
)

Expand All @@ -440,18 +438,16 @@ async def async_step_reauth_confirm(
errors["base"] = "invalid_pin"

# If all went right, update the config entry
if not errors:
self.hass.config_entries.async_update_entry(
self._entry,
else:
return self.async_update_reload_and_abort(
reauth_entry,
data={
CONF_ELMAX_PANEL_ID: self._entry.data[CONF_ELMAX_PANEL_ID],
CONF_ELMAX_PANEL_ID: reauth_entry.data[CONF_ELMAX_PANEL_ID],
CONF_ELMAX_PANEL_PIN: panel_pin,
CONF_ELMAX_USERNAME: username,
CONF_ELMAX_PASSWORD: password,
},
)
await self.hass.config_entries.async_reload(self._entry.entry_id)
return self.async_abort(reason="reauth_successful")

# Otherwise start over and show the relative error message
return self.async_show_form(
Expand Down
5 changes: 2 additions & 3 deletions homeassistant/components/fritzbox_callmonitor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady

from .base import FritzBoxPhonebook
from .const import CONF_PHONEBOOK, CONF_PREFIXES, PLATFORMS
Expand Down Expand Up @@ -42,8 +42,7 @@ async def async_setup_entry(
)
return False
except FritzConnectionException as ex:
_LOGGER.error("Invalid authentication: %s", ex)
return False
raise ConfigEntryAuthFailed from ex
except RequestsConnectionError as ex:
_LOGGER.error("Unable to connect to AVM FRITZ!Box call monitor: %s", ex)
raise ConfigEntryNotReady from ex
Expand Down
65 changes: 65 additions & 0 deletions homeassistant/components/fritzbox_callmonitor/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

from collections.abc import Mapping
from enum import StrEnum
from typing import Any, cast

Expand Down Expand Up @@ -65,6 +66,7 @@ class FritzBoxCallMonitorConfigFlow(ConfigFlow, domain=DOMAIN):

VERSION = 1

_entry: ConfigEntry
_host: str
_port: int
_username: str
Expand Down Expand Up @@ -209,6 +211,69 @@ async def async_step_phonebook(

return self._get_config_entry()

async def async_step_reauth(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle flow upon an API authentication error."""
self._entry = self._get_reauth_entry()
self._host = entry_data[CONF_HOST]
self._port = entry_data[CONF_PORT]
self._username = entry_data[CONF_USERNAME]
self._password = entry_data[CONF_PASSWORD]
self._phonebook_id = entry_data[CONF_PHONEBOOK]

return await self.async_step_reauth_confirm()

def _show_setup_form_reauth_confirm(
self, user_input: dict[str, Any], errors: dict[str, str] | None = None
) -> ConfigFlowResult:
"""Show the reauth form to the user."""
default_username = user_input.get(CONF_USERNAME)
return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema(
{
vol.Required(CONF_USERNAME, default=default_username): str,
vol.Required(CONF_PASSWORD): str,
}
),
description_placeholders={"host": self._host},
errors=errors or {},
)

async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Dialog that informs the user that reauth is required."""
if user_input is None:
return self._show_setup_form_reauth_confirm(
user_input={CONF_USERNAME: self._username}
)

self._username = user_input[CONF_USERNAME]
self._password = user_input[CONF_PASSWORD]

if (
error := await self.hass.async_add_executor_job(self._try_connect)
) is not ConnectResult.SUCCESS:
return self._show_setup_form_reauth_confirm(
user_input=user_input, errors={"base": error}
)

self.hass.config_entries.async_update_entry(
self._entry,
data={
CONF_HOST: self._host,
CONF_PORT: self._port,
CONF_USERNAME: self._username,
CONF_PASSWORD: self._password,
CONF_PHONEBOOK: self._phonebook_id,
SERIAL_NUMBER: self._serial_number,
},
)
await self.hass.config_entries.async_reload(self._entry.entry_id)
return self.async_abort(reason="reauth_successful")


class FritzBoxCallMonitorOptionsFlowHandler(OptionsFlow):
"""Handle a fritzbox_callmonitor options flow."""
Expand Down
10 changes: 9 additions & 1 deletion homeassistant/components/fritzbox_callmonitor/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,22 @@
"data": {
"phonebook": "Phonebook"
}
},
"reauth_confirm": {
"data": {
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]"
}
}
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
"insufficient_permissions": "User has insufficient permissions to access AVM FRITZ!Box settings and its phonebooks."
"insufficient_permissions": "User has insufficient permissions to access AVM FRITZ!Box settings and its phonebooks.",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"error": {
"insufficient_permissions": "[%key:component::fritzbox_callmonitor::config::abort::insufficient_permissions%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
}
},
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/hyperion/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ class HyperionConfigFlow(ConfigFlow, domain=DOMAIN):

VERSION = 1

unique_id: str

def __init__(self) -> None:
"""Instantiate config flow."""
self._data: dict[str, Any] = {}
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/recorder/models/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class LegacyLazyState(State):
"_attributes",
"_last_changed_ts",
"_last_updated_ts",
"_last_reported_ts",
"_context",
"attr_cache",
]
Expand Down
104 changes: 28 additions & 76 deletions homeassistant/components/spider/__init__.py
Original file line number Diff line number Diff line change
@@ -1,87 +1,39 @@
"""Support for Spider Smart devices."""
"""The Spider integration."""

import logging
from __future__ import annotations

from spiderpy.spiderapi import SpiderApi, SpiderApiException, UnauthorizedException
import voluptuous as vol

from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType

from .const import DEFAULT_SCAN_INTERVAL, DOMAIN, PLATFORMS

_LOGGER = logging.getLogger(__name__)

CONFIG_SCHEMA = vol.Schema(
vol.All(
cv.deprecated(DOMAIN),
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Optional(
CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL
): cv.time_period,
}
)
from homeassistant.helpers import issue_registry as ir

DOMAIN = "spider"


async def async_setup_entry(hass: HomeAssistant, _: ConfigEntry) -> bool:
"""Set up Spider from a config entry."""
ir.async_create_issue(
hass,
DOMAIN,
DOMAIN,
is_fixable=False,
severity=ir.IssueSeverity.ERROR,
translation_key="integration_removed",
translation_placeholders={
"link": "https://www.ithodaalderop.nl/additionelespiderproducten",
"entries": "/config/integrations/integration/spider",
},
),
extra=vol.ALLOW_EXTRA,
)


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up a config entry."""
hass.data[DOMAIN] = {}
if DOMAIN not in config:
return True

conf = config[DOMAIN]

if not hass.config_entries.async_entries(DOMAIN):
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=conf
)
)

return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Spider via config entry."""
try:
api = await hass.async_add_executor_job(
SpiderApi,
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
entry.data[CONF_SCAN_INTERVAL],
)
except UnauthorizedException:
_LOGGER.error("Authorization failed")
return False
except SpiderApiException as err:
_LOGGER.error("Can't connect to the Spider API: %s", err)
raise ConfigEntryNotReady from err

hass.data[DOMAIN][entry.entry_id] = api

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
)

return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload Spider entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if not unload_ok:
return False

hass.data[DOMAIN].pop(entry.entry_id)
"""Unload a config entry."""
if all(
config_entry.state is ConfigEntryState.NOT_LOADED
for config_entry in hass.config_entries.async_entries(DOMAIN)
if config_entry.entry_id != entry.entry_id
):
ir.async_delete_issue(hass, DOMAIN, DOMAIN)

return True
Loading

0 comments on commit 55e7b1c

Please sign in to comment.