Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add config flow #4

Merged
merged 3 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 14 additions & 34 deletions custom_components/hass_proxy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,32 @@
"""
Custom integration to integrate integration_blueprint with Home Assistant.
Custom integration to add a tiny proxy to Home Assistant.

For more details about this integration, please refer to
https://github.com/ludeeus/integration_blueprint
https://github.com/dermotduffy/hass-proxy
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.loader import async_get_loaded_integration

from .api import IntegrationBlueprintApiClient
from .coordinator import BlueprintDataUpdateCoordinator
from .data import IntegrationBlueprintData
from .const import LOGGER

if TYPE_CHECKING:
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant

from .data import IntegrationBlueprintConfigEntry
from .data import HASSProxyData

PLATFORMS: list[Platform] = [
Platform.SENSOR,
Platform.BINARY_SENSOR,
Platform.SWITCH,
]
PLATFORMS: list[Platform] = []


# https://developers.home-assistant.io/docs/config_entries_index/#setting-up-an-entry
async def async_setup_entry(
hass: HomeAssistant,
entry: IntegrationBlueprintConfigEntry,
entry: HASSProxyData,
) -> bool:
"""Set up this integration using UI."""
coordinator = BlueprintDataUpdateCoordinator(
hass=hass,
)
entry.runtime_data = IntegrationBlueprintData(
client=IntegrationBlueprintApiClient(
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
session=async_get_clientsession(hass),
),
integration=async_get_loaded_integration(hass, entry.domain),
coordinator=coordinator,
)

# https://developers.home-assistant.io/docs/integration_fetching_data#coordinated-single-api-poll-for-data-for-all-entities
await coordinator.async_config_entry_first_refresh()
"""Set up this integration."""
LOGGER.info("HASSPROXY Setting up entry %s", entry.entry_id)

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
entry.async_on_unload(entry.add_update_listener(async_reload_entry))
Expand All @@ -59,16 +36,19 @@ async def async_setup_entry(

async def async_unload_entry(
hass: HomeAssistant,
entry: IntegrationBlueprintConfigEntry,
entry: HASSProxyData,
) -> bool:
"""Handle removal of an entry."""
LOGGER.info("HASSPROXY Unloading entry %s", entry.entry_id)
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)


async def async_reload_entry(
hass: HomeAssistant,
entry: IntegrationBlueprintConfigEntry,
entry: HASSProxyData,
) -> None:
"""Reload config entry."""
LOGGER.info("HASSPROXY Reloading entry %s", entry.entry_id)

await async_unload_entry(hass, entry)
await async_setup_entry(hass, entry)
101 changes: 0 additions & 101 deletions custom_components/hass_proxy/api.py

This file was deleted.

61 changes: 0 additions & 61 deletions custom_components/hass_proxy/binary_sensor.py

This file was deleted.

92 changes: 41 additions & 51 deletions custom_components/hass_proxy/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,81 +1,71 @@
"""Adds config flow for Blueprint."""
"""Config flow for HASS Proxy."""

from __future__ import annotations

import voluptuous as vol
from homeassistant import config_entries, data_entry_flow
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.helpers import selector
from homeassistant.helpers.aiohttp_client import async_create_clientsession

from .api import (
IntegrationBlueprintApiClient,
IntegrationBlueprintApiClientAuthenticationError,
IntegrationBlueprintApiClientCommunicationError,
IntegrationBlueprintApiClientError,
)
from .const import DOMAIN, LOGGER
from .const import CONF_URLS, DOMAIN


class BlueprintFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Config flow for Blueprint."""
class HASSProxyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): # type: ignore[call-arg,misc]
"""Config flow for HASS Proxy."""

VERSION = 1

@staticmethod
@callback # type: ignore[misc]
def async_get_options_flow(
config_entry: config_entries.ConfigEntry,
) -> HASSProxyOptionsFlowHandler:
"""Get the Frigate Options flow."""
return HASSProxyOptionsFlowHandler(config_entry)

async def async_step_user(
self,
user_input: dict | None = None,
) -> data_entry_flow.FlowResult:
) -> config_entries.ConfigFlowResult:
"""Handle a flow initialized by the user."""
_errors = {}
if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")

return self.async_create_entry(title="HASS Proxy", data=user_input or {})


class HASSProxyOptionsFlowHandler(config_entries.OptionsFlow):
"""Options flow for Blueprint."""

VERSION = 1

def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
"""Initialize an options flow."""
self._config_entry = config_entry

async def async_step_init(
self,
user_input: dict | None = None,
) -> config_entries.ConfigFlowResult:
"""Manage the options."""
if user_input is not None:
try:
await self._test_credentials(
username=user_input[CONF_USERNAME],
password=user_input[CONF_PASSWORD],
)
except IntegrationBlueprintApiClientAuthenticationError as exception:
LOGGER.warning(exception)
_errors["base"] = "auth"
except IntegrationBlueprintApiClientCommunicationError as exception:
LOGGER.error(exception)
_errors["base"] = "connection"
except IntegrationBlueprintApiClientError as exception:
LOGGER.exception(exception)
_errors["base"] = "unknown"
else:
return self.async_create_entry(
title=user_input[CONF_USERNAME],
data=user_input,
)
return self.async_create_entry(
data=user_input,
)

return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{
vol.Required(
CONF_USERNAME,
default=(user_input or {}).get(CONF_USERNAME, vol.UNDEFINED),
CONF_URLS,
default=(user_input or {}).get(CONF_URLS, vol.UNDEFINED),
): selector.TextSelector(
selector.TextSelectorConfig(
type=selector.TextSelectorType.TEXT,
),
),
vol.Required(CONF_PASSWORD): selector.TextSelector(
selector.TextSelectorConfig(
type=selector.TextSelectorType.PASSWORD,
multiline=True,
),
),
},
),
errors=_errors,
)

async def _test_credentials(self, username: str, password: str) -> None:
"""Validate credentials."""
client = IntegrationBlueprintApiClient(
username=username,
password=password,
session=async_create_clientsession(self.hass),
)
await client.async_get_data()
9 changes: 5 additions & 4 deletions custom_components/hass_proxy/const.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Constants for integration_blueprint."""
"""Constants for hass_proxy."""

from logging import Logger, getLogger

LOGGER: Logger = getLogger(__package__)
DOMAIN = "hass_proxy"

CONF_URLS = "urls"

DOMAIN = "integration_blueprint"
ATTRIBUTION = "Data provided by http://jsonplaceholder.typicode.com/"
LOGGER: Logger = getLogger(__package__)
Loading