一键导入
homeassistant-config-flow
Patterns for Home Assistant config flows, discovery handlers, options flows, and reauth for custom components
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Patterns for Home Assistant config flows, discovery handlers, options flows, and reauth for custom components
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
How to create, update, and manage Changesets for release preparation in this repository
Guidance for using correct energy and power metrics in Home Assistant energy features
High-level Home Assistant integration best practices, quality scale cues, and testing/CI expectations for custom components
Project-specific patterns for the Marstek integration (config flow, coordinator, scanner, entities, translations)
Practical test/CI playbook for Home Assistant custom components (config flow, coordinator, entities, diagnostics)
Repo-specific guidance for maintaining the Marstek integration (UDP Open API, polling, discovery/scanner) in a Home Assistant-friendly way
| name | homeassistant-config-flow |
| description | Patterns for Home Assistant config flows, discovery handlers, options flows, and reauth for custom components |
Use this skill when adding or adjusting setup flows, discovery handlers, options flows, or reauth for this integration.
config_flow.pyasync_step_user: show form when user_input is None; on submit, validate connectivity; return errors with keys (cannot_connect, invalid_auth, already_configured).async_step_dhcp / async_step_zeroconf / async_step_integration_discovery: deduplicate via MAC/unique ID; if existing entry with new host, update data and abort with already_configured.async_step_confirm: for discovery flows, prefill known values and ask user to confirm.Reauth handles authentication/connection failures gracefully, allowing users to update credentials or IP addresses without removing the integration.
async_step_reauth(entry_data) - Called when reauth is triggeredasync_step_reauth_confirm(user_input) - Show form, validate, update entryfrom homeassistant.config_entries import SOURCE_REAUTH
async def async_step_reauth(
self, entry_data: dict[str, Any]
) -> ConfigFlowResult:
"""Handle reauth when device becomes unreachable."""
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm reauth dialog."""
errors: dict[str, str] = {}
reauth_entry = self._get_reauth_entry()
if user_input is not None:
host = user_input.get(CONF_HOST)
try:
device_info = await get_device_info(host=host, port=port)
if device_info:
# Validate unique ID unchanged
await self.async_set_unique_id(device_info["ble_mac"])
self._abort_if_unique_id_mismatch()
# Preferred: use async_update_reload_and_abort helper
return self.async_update_reload_and_abort(
reauth_entry,
data_updates={CONF_HOST: host},
)
errors["base"] = "cannot_connect"
except (OSError, TimeoutError):
errors["base"] = "cannot_connect"
return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema({vol.Required(CONF_HOST): cv.string}),
errors=errors,
description_placeholders={"host": reauth_entry.data.get(CONF_HOST, "")},
)
self._get_reauth_entry() - Get the config entry being reauthenticatedself.async_update_reload_and_abort() - Update entry, reload, and abort with reauth_successful (preferred)self._abort_if_unique_id_mismatch() - Ensure the same device is being reauthenticatedif self.source == SOURCE_REAUTH:From coordinator or setup when connection fails repeatedly:
entry.async_start_reauth(hass)
Add to strings.json and translations/en.json:
"reauth_confirm": {
"title": "Reconnect Device",
"description": "The device at {host} is not responding.",
"data": {"host": "IP address"}
}
And abort reason:
"abort": {
"reauth_successful": "Device reconnected successfully"
}
Use section() to group related fields into collapsible sections:
from homeassistant.data_entry_flow import section
data_schema = {
vol.Required("host"): str,
vol.Required("advanced_options"): section(
vol.Schema({
vol.Optional("timeout", default=30): int,
vol.Optional("retry_count", default=3): int,
}),
{"collapsed": True}, # Initially collapsed
)
}
from homeassistant.helpers.schema_config_entry_flow import add_suggested_values_to_schema
return self.async_show_form(
data_schema=add_suggested_values_to_schema(
OPTIONS_SCHEMA, self.config_entry.options
)
)
Use recognized keys (username, password) or TextSelector with autocomplete:
vol.Required(CONF_USERNAME): TextSelector(
TextSelectorConfig(type=TextSelectorType.EMAIL, autocomplete="username")
),
For frozen configuration shown in options:
vol.Optional(CONF_DEVICE_ID): EntitySelector(
EntitySelectorConfig(read_only=True)
),
return self.async_show_menu(
step_id="user",
menu_options=["discovery", "manual"],
description_placeholders={"model": "Venus A"},
)
if not self.task:
self.task = self.hass.async_create_task(long_running_operation())
if not self.task.done():
return self.async_show_progress(
progress_action="connecting",
progress_task=self.task,
)
return self.async_show_progress_done(next_step_id="finish")
async_get_options_flow to return an OptionsFlowHandler.entry.options; keep credentials in entry.data.entry.add_update_listener in __init__.py to reload on options change.add_suggested_values_to_schema() to pre-fill current options.self._abort_if_unique_id_configured().already_configured.strings.json and mirror to translations/en.json.cannot_connect, invalid_auth, already_configured, unknown.description_placeholders when useful (e.g., {ip_address}).Config flow forms are translated via strings.json:
{
"config": {
"step": {
"user": {
"title": "Set up Marstek",
"description": "Connect to your {model} device.",
"data": {
"host": "Hostname or IP",
"port": "Port"
},
"data_description": {
"host": "The IP address of your Marstek device on the local network"
},
"sections": {
"advanced_options": {
"name": "Advanced Options",
"description": "Optional configuration"
}
}
}
},
"error": {
"cannot_connect": "Cannot connect to device",
"invalid_auth": "Invalid authentication"
},
"abort": {
"already_configured": "Device is already configured",
"reauth_successful": "Reauthentication successful"
}
}
}
Form translation keys:
title - Form titledescription - Form description (supports placeholders via description_placeholders)data - Field labels (keyed by field name)data_description - Field help text (shown below field)sections - Section names and descriptions (for section() fields)