from __future__ import annotations import logging import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_ENTITY_ID from homeassistant.core import callback from homeassistant.helpers import selector from .const import ( CONF_ANGLE_ADDRESS, CONF_ANGLE_STATE_ADDRESS, CONF_KNX_ENTRY_ID, CONF_MOVE_LONG_ADDRESS, CONF_MOVE_SHORT_ADDRESS, CONF_POSITION_ADDRESS, CONF_POSITION_STATE_ADDRESS, CONF_STATE_ADDRESS, CONF_STOP_ADDRESS, DOMAIN, ) _LOGGER = logging.getLogger(__name__) KNX_DOMAIN = "knx" class HAKnxBridgeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 async def async_step_user(self, user_input: dict | None = None): knx_entries = self.hass.config_entries.async_entries(KNX_DOMAIN) if not knx_entries: return self.async_abort(reason="knx_not_configured") if user_input is not None: return self.async_create_entry( title="HA KNX Bridge", data={CONF_KNX_ENTRY_ID: user_input[CONF_KNX_ENTRY_ID]}, ) options = [ {"value": entry.entry_id, "label": entry.title or entry.entry_id} for entry in knx_entries ] schema = vol.Schema( { vol.Required(CONF_KNX_ENTRY_ID): selector.SelectSelector( selector.SelectSelectorConfig(options=options, mode="dropdown") ) } ) return self.async_show_form(step_id="user", data_schema=schema) @staticmethod @callback def async_get_supported_subentry_types(config_entry): return { "binary_sensor": config_entries.SubentryType( name="Binary Sensor Port", flow_class=BinarySensorPortSubentryFlow ), "cover": config_entries.SubentryType( name="Cover Port", flow_class=CoverPortSubentryFlow ), } class BinarySensorPortSubentryFlow(config_entries.ConfigSubentryFlow): VERSION = 1 async def async_step_user(self, user_input: dict | None = None): if user_input is not None: title = _entity_title(self.hass, user_input[CONF_ENTITY_ID]) return self.async_create_entry(title=title, data=user_input) schema = vol.Schema( { vol.Required(CONF_ENTITY_ID): selector.EntitySelector( selector.EntitySelectorConfig(domain=["binary_sensor"]) ), vol.Optional(CONF_STATE_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), } ) return self.async_show_form(step_id="user", data_schema=schema) class CoverPortSubentryFlow(config_entries.ConfigSubentryFlow): VERSION = 1 async def async_step_user(self, user_input: dict | None = None): if user_input is not None: title = _entity_title(self.hass, user_input[CONF_ENTITY_ID]) return self.async_create_entry(title=title, data=user_input) schema = vol.Schema( { vol.Required(CONF_ENTITY_ID): selector.EntitySelector( selector.EntitySelectorConfig(domain=["cover"]) ), vol.Optional(CONF_MOVE_LONG_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), vol.Optional(CONF_MOVE_SHORT_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), vol.Optional(CONF_STOP_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), vol.Optional(CONF_POSITION_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), vol.Optional(CONF_POSITION_STATE_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), vol.Optional(CONF_ANGLE_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), vol.Optional(CONF_ANGLE_STATE_ADDRESS): selector.TextSelector( selector.TextSelectorConfig(type="text") ), } ) return self.async_show_form(step_id="user", data_schema=schema) def _entity_title(hass, entity_id: str) -> str: state = hass.states.get(entity_id) if state is None: return entity_id return state.attributes.get("friendly_name", entity_id)