diff --git a/custom_components/hitachi_yutaki/config_flow.py b/custom_components/hitachi_yutaki/config_flow.py index bfe07eb..2647a3b 100644 --- a/custom_components/hitachi_yutaki/config_flow.py +++ b/custom_components/hitachi_yutaki/config_flow.py @@ -29,14 +29,30 @@ _LOGGER = logging.getLogger(__name__) -STEP_USER_DATA_SCHEMA = vol.Schema( +# Schema for mode selection (simple/advanced) +MODE_SCHEMA = vol.Schema( + { + vol.Required("advanced_mode", default=False): bool, + } +) + +# Basic schema with essential options only +BASE_SCHEMA = vol.Schema( { vol.Required(CONF_HOST): str, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, + } +) + +# Advanced schema with all available options +ADVANCED_SCHEMA = vol.Schema( + { + vol.Required(CONF_HOST): str, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, vol.Required(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Required(CONF_SLAVE, default=DEFAULT_SLAVE): vol.All( cv.positive_int, vol.Range(min=1, max=247) ), - vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, vol.Optional( CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL ): cv.positive_int, @@ -50,18 +66,63 @@ class HitachiYutakiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 + def __init__(self): + """Initialize the config flow.""" + # Store the mode choice and user input throughout the flow + self.advanced_mode = False + self.user_input = None + async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> FlowResult: - """Handle the initial step.""" + """Initial step - redirect to mode selection.""" + return self.async_show_form( + step_id="choose_mode", + data_schema=MODE_SCHEMA, + ) + + async def async_step_choose_mode( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: + """Let user choose between simple and advanced configuration mode.""" + if user_input is not None: + # Store the mode choice and move to configuration step + self.advanced_mode = user_input["advanced_mode"] + return await self.async_step_configure() + + return self.async_show_form( + step_id="choose_mode", + data_schema=MODE_SCHEMA, + ) + + async def async_step_configure( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: + """Handle the configuration step.""" errors: dict[str, str] = {} + # Select schema based on chosen mode + schema = ADVANCED_SCHEMA if self.advanced_mode else BASE_SCHEMA if user_input is None: + # Show the form if no user input return self.async_show_form( - step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors + step_id="configure", + data_schema=schema, + errors=errors, ) + # If in simple mode, add default values for advanced options + if not self.advanced_mode: + user_input = { + **user_input, + CONF_PORT: DEFAULT_PORT, + CONF_SLAVE: DEFAULT_SLAVE, + CONF_SCAN_INTERVAL: DEFAULT_SCAN_INTERVAL, + "dev_mode": False, + } + try: + # Try to connect to the Modbus device from pymodbus.client import ModbusTcpClient from pymodbus.exceptions import ModbusException @@ -73,11 +134,11 @@ async def async_step_user( if not client.connect(): errors["base"] = "cannot_connect" return self.async_show_form( - step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors + step_id="configure", data_schema=schema, errors=errors ) try: - # Check unit model + # Verify the device by checking unit model result = await self.hass.async_add_executor_job( client.read_holding_registers, REGISTER_UNIT_MODEL, @@ -88,10 +149,10 @@ async def async_step_user( if result.isError(): errors["base"] = "invalid_slave" return self.async_show_form( - step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors + step_id="configure", data_schema=schema, errors=errors ) - # Check central control mode + # Check if central control mode is correct mode_result = await self.hass.async_add_executor_job( client.read_holding_registers, REGISTER_CENTRAL_CONTROL_MODE, @@ -102,16 +163,16 @@ async def async_step_user( if mode_result.isError(): errors["base"] = "modbus_error" return self.async_show_form( - step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors + step_id="configure", data_schema=schema, errors=errors ) if mode_result.registers[0] != CENTRAL_CONTROL_MODE_MAP["air"]: errors["base"] = "invalid_central_control_mode" return self.async_show_form( - step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors + step_id="configure", data_schema=schema, errors=errors ) - # Create entry if everything is OK + # Create entry if all validations pass await self.async_set_unique_id( f"{user_input[CONF_HOST]}_{user_input[CONF_SLAVE]}" ) @@ -135,5 +196,5 @@ async def async_step_user( errors["base"] = "unknown" return self.async_show_form( - step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors + step_id="configure", data_schema=schema, errors=errors )