Skip to content

Commit

Permalink
Merge pull request #4 from dermotduffy/logical-earwig
Browse files Browse the repository at this point in the history
Add config flow
  • Loading branch information
dermotduffy authored Oct 16, 2024
2 parents 2577c92 + 8db0408 commit 7e326cb
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 474 deletions.
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

0 comments on commit 7e326cb

Please sign in to comment.