-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Align with Home Assistant style guidelines * Update dependencies * Switch VS Code format provider * Update manifest * Refactor config flow and init * Remove tests * Handle offline setup failure * Add comments * Use latest code for pyglowmarkt * Rewrite the whole of sensor.py * Update hacs.json and bump minimum hass version * Format code with black and isort * Remove blank line * Update readme * Add note about changeover Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
- Loading branch information
1 parent
2565cf7
commit e9d4219
Showing
21 changed files
with
584 additions
and
1,030 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,51 @@ | ||
"""The Hildebrand Glow integration.""" | ||
import asyncio | ||
from typing import Any, Dict | ||
"""The Hildebrand Glow (DCC) integration.""" | ||
from __future__ import annotations | ||
|
||
import voluptuous as vol | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import HomeAssistant | ||
|
||
from .const import APP_ID, DOMAIN | ||
from .glow import Glow | ||
import logging | ||
|
||
CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA) | ||
from glowmarkt import BrightClient | ||
import requests | ||
|
||
PLATFORMS = ["sensor"] | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.const import Platform | ||
from homeassistant.core import HomeAssistant | ||
from homeassistant.exceptions import ConfigEntryNotReady | ||
|
||
from .const import DOMAIN | ||
|
||
async def async_setup(hass: HomeAssistant, _unused: Dict[str, Any]) -> bool: | ||
"""Set up the Hildebrand Glow component.""" | ||
hass.data[DOMAIN] = {} | ||
_LOGGER = logging.getLogger(__name__) | ||
|
||
return True | ||
PLATFORMS: list[Platform] = [Platform.SENSOR] | ||
|
||
|
||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
"""Set up Hildebrand Glow from a config entry.""" | ||
glow = Glow(APP_ID, entry.data["token"]) | ||
hass.data[DOMAIN][entry.entry_id] = glow | ||
|
||
for component in PLATFORMS: | ||
hass.async_create_task( | ||
hass.config_entries.async_forward_entry_setup(entry, component) | ||
"""Set up Hildebrand Glow (DCC) from a config entry.""" | ||
hass.data.setdefault(DOMAIN, {}) | ||
# Authenticate with the API | ||
try: | ||
glowmarkt = await hass.async_add_executor_job( | ||
BrightClient, entry.data["username"], entry.data["password"] | ||
) | ||
except requests.Timeout as ex: | ||
raise ConfigEntryNotReady(f"Timeout: {ex}") from ex | ||
except requests.exceptions.ConnectionError as ex: | ||
raise ConfigEntryNotReady(f"Cannot connect: {ex}") from ex | ||
except Exception as ex: # pylint: disable=broad-except | ||
raise ConfigEntryNotReady(f"Unexpected exception: {ex}") from ex | ||
else: | ||
_LOGGER.debug("Successful Post to %sauth", glowmarkt.url) | ||
|
||
# Set API object | ||
hass.data[DOMAIN][entry.entry_id] = glowmarkt | ||
|
||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) | ||
|
||
return True | ||
|
||
|
||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
"""Unload a config entry.""" | ||
unload_ok = all( | ||
await asyncio.gather( | ||
*[ | ||
hass.config_entries.async_forward_entry_unload( | ||
entry, component) | ||
for component in PLATFORMS | ||
] | ||
) | ||
) | ||
if unload_ok: | ||
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): | ||
hass.data[DOMAIN].pop(entry.entry_id) | ||
|
||
return unload_ok |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,73 +1,83 @@ | ||
"""Config flow for Hildebrand Glow integration.""" | ||
"""Config flow for Hildebrand Glow (DCC) integration.""" | ||
from __future__ import annotations | ||
|
||
import logging | ||
from typing import Any, Dict | ||
from typing import Any | ||
|
||
from glowmarkt import BrightClient | ||
import requests | ||
import voluptuous as vol | ||
from homeassistant import config_entries, core, data_entry_flow | ||
|
||
from .const import APP_ID, DOMAIN | ||
from .glow import CannotConnect, Glow, InvalidAuth | ||
from homeassistant import config_entries | ||
from homeassistant.core import HomeAssistant | ||
from homeassistant.data_entry_flow import FlowResult | ||
|
||
from .const import DOMAIN | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
DATA_SCHEMA = vol.Schema( | ||
STEP_USER_DATA_SCHEMA = vol.Schema( | ||
{ | ||
vol.Required("username"): str, | ||
vol.Required("password"): str, | ||
} | ||
) | ||
|
||
|
||
def config_object(data: dict, glow: Dict[str, Any]) -> Dict[str, Any]: | ||
"""Prepare a ConfigEntity with authentication data and a temporary token.""" | ||
return { | ||
"name": glow["name"], | ||
"username": data["username"], | ||
"password": data["password"], | ||
"token": glow["token"], | ||
"token_exp": glow["exp"], | ||
} | ||
|
||
|
||
async def validate_input(hass: core.HomeAssistant, data: dict) -> Dict[str, Any]: | ||
async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, Any]: | ||
"""Validate the user input allows us to connect. | ||
Data has the keys from DATA_SCHEMA with values provided by the user. | ||
Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user. | ||
""" | ||
glow = await hass.async_add_executor_job( | ||
Glow.authenticate, APP_ID, data["username"], data["password"] | ||
glowmarkt = await hass.async_add_executor_job( | ||
BrightClient, data["username"], data["password"] | ||
) | ||
_LOGGER.debug("Successful Post to %sauth", glowmarkt.url) | ||
|
||
# Return some info we want to store in the config entry. | ||
return config_object(data, glow) | ||
# Return title of the entry to be added | ||
return {"title": "Hildebrand Glow (DCC)"} | ||
|
||
|
||
class DomainConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): | ||
"""Handle a config flow for Hildebrand Glow.""" | ||
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): | ||
"""Handle a config flow for Hildebrand Glow (DCC).""" | ||
|
||
VERSION = 1 | ||
CONNECTION_CLASS = config_entries.SOURCE_USER | ||
|
||
async def async_step_user( | ||
self, user_input: Dict = None | ||
) -> data_entry_flow.FlowResult: | ||
self, user_input: dict[str, Any] | None = None | ||
) -> FlowResult: | ||
"""Handle the initial step.""" | ||
# If left empty, simply show the form again | ||
if user_input is None: | ||
return self.async_show_form( | ||
step_id="user", data_schema=STEP_USER_DATA_SCHEMA | ||
) | ||
|
||
errors = {} | ||
if user_input is not None: | ||
try: | ||
if self.hass is None: | ||
raise AssertionError | ||
info = await validate_input(self.hass, user_input) | ||
|
||
return self.async_create_entry(title=info["name"], data=info) | ||
except CannotConnect: | ||
errors["base"] = "cannot_connect" | ||
except InvalidAuth: | ||
|
||
# Test authenticating with the API | ||
try: | ||
info = await validate_input(self.hass, user_input) | ||
except requests.Timeout as ex: | ||
_LOGGER.debug("Timeout: %s", ex) | ||
errors["base"] = "timeout_connect" | ||
except requests.exceptions.ConnectionError as ex: | ||
_LOGGER.debug("Cannot connect: %s", ex) | ||
errors["base"] = "cannot_connect" | ||
# Can't use the RuntimeError exception from the library as it's not a subclass of Exception | ||
except Exception as ex: # pylint: disable=broad-except | ||
if "Authentication failed" in str(ex): | ||
_LOGGER.debug("Authentication Failed") | ||
errors["base"] = "invalid_auth" | ||
elif "Expected an authentication token" in str(ex): | ||
_LOGGER.debug("Expected an authentication token but didn't get one") | ||
errors["base"] = "invalid_auth" | ||
except Exception: # pylint: disable=broad-except | ||
_LOGGER.exception("Unexpected exception") | ||
else: | ||
_LOGGER.exception("Unexpected exception: %s", ex) | ||
errors["base"] = "unknown" | ||
else: | ||
return self.async_create_entry(title=info["title"], data=user_input) | ||
|
||
return self.async_show_form( | ||
step_id="user", data_schema=DATA_SCHEMA, errors=errors | ||
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
"""Constants for the Hildebrand Glow integration.""" | ||
"""Constants for the Hildebrand Glow (DCC) integration.""" | ||
|
||
DOMAIN = "hildebrandglow_dcc" | ||
APP_ID = "b0f1b774-a586-4f72-9edd-27ead8aa7a8d" |
Oops, something went wrong.