Skip to content

Commit

Permalink
feat: Config Flow with advanced mode
Browse files Browse the repository at this point in the history
  • Loading branch information
alepee committed Nov 24, 2024
1 parent aed4fab commit fdc5f75
Showing 1 changed file with 73 additions and 12 deletions.
85 changes: 73 additions & 12 deletions custom_components/hitachi_yutaki/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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

Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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]}"
)
Expand All @@ -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
)

0 comments on commit fdc5f75

Please sign in to comment.