async def async_step_secure_manual(self, user_input: dict | None = None ) -> FlowResult: """Configure ip secure manually.""" errors: dict = {} if user_input is not None: assert self._tunneling_config entry_data = self._tunneling_config | KNXConfigEntryData( connection_type=CONF_KNX_TUNNELING_TCP_SECURE, device_authentication=user_input[ CONF_KNX_SECURE_DEVICE_AUTHENTICATION], user_id=user_input[CONF_KNX_SECURE_USER_ID], user_password=user_input[CONF_KNX_SECURE_USER_PASSWORD], ) return self.async_create_entry( title=f"Secure Tunneling @ {self._tunneling_config[CONF_HOST]}", data=entry_data, ) fields = { vol.Required(CONF_KNX_SECURE_USER_ID, default=2): vol.All( selector.NumberSelector( selector.NumberSelectorConfig( min=1, max=127, mode=selector.NumberSelectorMode.BOX), ), vol.Coerce(int), ), vol.Required(CONF_KNX_SECURE_USER_PASSWORD): selector.TextSelector( selector.TextSelectorConfig( type=selector.TextSelectorType.PASSWORD), ), vol.Required(CONF_KNX_SECURE_DEVICE_AUTHENTICATION): selector.TextSelector( selector.TextSelectorConfig( type=selector.TextSelectorType.PASSWORD), ), } return self.async_show_form(step_id="secure_manual", data_schema=vol.Schema(fields), errors=errors)
async def async_step_init(self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Manage SQL options.""" errors = {} if user_input is not None: db_url = user_input[CONF_DB_URL] query = user_input[CONF_QUERY] column = user_input[CONF_COLUMN_NAME] try: validate_sql_select(query) await self.hass.async_add_executor_job(validate_query, db_url, query, column) except SQLAlchemyError: errors["db_url"] = "db_url_invalid" except ValueError: errors["query"] = "query_invalid" else: return self.async_create_entry( title="", data={ CONF_NAME: self.entry.title, **self.entry.options, **user_input, }, ) return self.async_show_form( step_id="init", data_schema=vol.Schema({ vol.Required( CONF_DB_URL, description={ "suggested_value": self.entry.options[CONF_DB_URL] }, ): selector.TextSelector(), vol.Required( CONF_QUERY, description={ "suggested_value": self.entry.options[CONF_QUERY] }, ): selector.TextSelector( selector.TextSelectorConfig(multiline=True)), vol.Required( CONF_COLUMN_NAME, description={ "suggested_value": self.entry.options[CONF_COLUMN_NAME] }, ): selector.TextSelector(), vol.Optional( CONF_UNIT_OF_MEASUREMENT, description={ "suggested_value": self.entry.options.get(CONF_UNIT_OF_MEASUREMENT) }, ): selector.TextSelector(), vol.Optional( CONF_VALUE_TEMPLATE, description={ "suggested_value": self.entry.options.get(CONF_VALUE_TEMPLATE) }, ): selector.TemplateSelector(), }), errors=errors, )
from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import selector from .const import CONF_COLUMN_NAME, CONF_QUERY, DOMAIN _LOGGER = logging.getLogger(__name__) DATA_SCHEMA = vol.Schema({ vol.Required(CONF_NAME, default="Select SQL Query"): selector.TextSelector(), vol.Optional(CONF_DB_URL): selector.TextSelector(), vol.Required(CONF_COLUMN_NAME): selector.TextSelector(), vol.Required(CONF_QUERY): selector.TextSelector(selector.TextSelectorConfig(multiline=True)), vol.Optional(CONF_UNIT_OF_MEASUREMENT): selector.TextSelector(), vol.Optional(CONF_VALUE_TEMPLATE): selector.TemplateSelector(), }) def validate_sql_select(value: str) -> str | None: """Validate that value is a SQL SELECT query.""" if not value.lstrip().lower().startswith("select"): raise ValueError("Incorrect Query") return value def validate_query(db_url: str, query: str, column: str) -> bool:
from homeassistant import config_entries from homeassistant.const import CONF_API_KEY, CONF_NAME, CONF_WEEKDAY, WEEKDAYS from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import selector from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import CONF_FROM, CONF_TIME, CONF_TO, DOMAIN from .util import create_unique_id ERROR_INVALID_AUTH = "Source: Security, message: Invalid authentication" ERROR_INVALID_ROUTE = "No FerryAnnouncement found" DATA_SCHEMA = vol.Schema({ vol.Required(CONF_API_KEY): selector.TextSelector(selector.TextSelectorConfig()), vol.Required(CONF_FROM): selector.TextSelector(selector.TextSelectorConfig()), vol.Optional(CONF_TO): selector.TextSelector(selector.TextSelectorConfig()), vol.Optional(CONF_TIME): selector.TimeSelector(selector.TimeSelectorConfig()), vol.Required(CONF_WEEKDAY, default=WEEKDAYS): selector.SelectSelector( selector.SelectSelectorConfig( options=WEEKDAYS, multiple=True, mode=selector.SelectSelectorMode.DROPDOWN, )), }) DATA_SCHEMA_REAUTH = vol.Schema({
async def _show_options_form( self, uinput=None, errors=None, placehoders=None ): # pylint: disable=unused-argument return self.async_show_form( step_id="init", data_schema=vol.Schema( { vol.Optional( CONF_SERVICE_NAME, description={ "suggested_value": self.default(CONF_SERVICE_NAME, uinput) }, ): cv.string, vol.Optional( CONF_SERVICE_DATA2, description={ "suggested_value": self.default(CONF_SERVICE_DATA2, uinput) }, ): selector.TemplateSelector(), vol.Optional( CONF_INCLUDED_FOLDERS, description={ "suggested_value": self.default( CONF_INCLUDED_FOLDERS, uinput ) }, ): selector.TextSelector( selector.TextSelectorConfig(multiline=True) ), vol.Optional( CONF_HEADER, description={ "suggested_value": self.default(CONF_HEADER, uinput) }, ): cv.string, vol.Optional( CONF_REPORT_PATH, description={ "suggested_value": self.default(CONF_REPORT_PATH, uinput) }, ): cv.string, vol.Optional( CONF_IGNORED_ITEMS, description={ "suggested_value": self.default(CONF_IGNORED_ITEMS, uinput) }, ): selector.TextSelector( selector.TextSelectorConfig(multiline=True) ), vol.Optional( CONF_IGNORED_STATES, description={ "suggested_value": self.default(CONF_IGNORED_STATES, uinput) }, ): selector.TextSelector( selector.TextSelectorConfig(multiline=True) ), vol.Optional( CONF_CHUNK_SIZE, description={ "suggested_value": self.default(CONF_CHUNK_SIZE, uinput) }, ): cv.positive_int, vol.Optional( CONF_IGNORED_FILES, description={ "suggested_value": self.default(CONF_IGNORED_FILES, uinput) }, ): selector.TextSelector( selector.TextSelectorConfig(multiline=True) ), vol.Optional( CONF_COLUMNS_WIDTH, description={ "suggested_value": self.default(CONF_COLUMNS_WIDTH, uinput) }, ): cv.string, vol.Optional( CONF_STARTUP_DELAY, description={ "suggested_value": self.default(CONF_STARTUP_DELAY, uinput) }, ): cv.positive_int, vol.Optional( CONF_FRIENDLY_NAMES, description={ "suggested_value": self.default(CONF_FRIENDLY_NAMES, uinput) }, ): cv.boolean, vol.Optional( CONF_CHECK_LOVELACE, description={ "suggested_value": self.default(CONF_CHECK_LOVELACE, uinput) }, ): cv.boolean, } ), errors=errors or {}, description_placeholders=placehoders or {}, )