Skip to content

Data entry flow previews#3081

Draft
iluvdata wants to merge 14 commits into
home-assistant:masterfrom
iluvdata:data-entry-flow-previews
Draft

Data entry flow previews#3081
iluvdata wants to merge 14 commits into
home-assistant:masterfrom
iluvdata:data-entry-flow-previews

Conversation

@iluvdata

@iluvdata iluvdata commented May 1, 2026

Copy link
Copy Markdown

Proposed change

Add documentation for using data entry flow previews.

Type of change

  • Document existing features within Home Assistant
  • Document new or changing features for which there is an existing pull request elsewhere
  • Spelling or grammatical corrections, or rewording for improved clarity
  • Changes to the backend of this documentation
  • Remove stale or deprecated documentation

Checklist

  • I have read and followed the documentation guidelines.
  • I have verified that my changes render correctly in the documentation.

Additional information

Creating an integration config flow with previews took hours of reverse engineering existing code and detailed review of existing components that use previews (for example):

  • homeassistant.components.templates
  • homeassistant.components.group

This additional documentation seeks to help others to avoid this deep dive into the inner workings of the core and frontend to get previews working in their code. Please note the use of domain in the code is dependent on the frontend PR referenced below. We should discuss if we should use the key "domain" or something like "entity_domain" which might be a bit more clear.

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive "Entity previews" guide for config, option, subentry, and repair flows: explains live input previews, validation with client-side error responses, and how preview updates (state, attributes, or errors) are forwarded to the frontend.
    • Includes an example preview implementation, instructions for registering preview handlers, how to enable previews when showing forms, and a frontend fallback tip for missing domain info.

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an "Entity previews" section to data entry flow docs describing a websocket preview command, runtime preview entity pattern, registration hook, and how to enable previews from async_show_form. Covers validation/error messages and frontend domain fallback behavior. (≤50 words)

Changes

Entity Previews Documentation

Layer / File(s) Summary
Overview / New section
docs/data_entry_flow_index.md
Adds an "Entity previews" section describing supported flow types and a four-step implementation guide.
WebSocket command (example)
docs/data_entry_flow_index.md
Documents a preview_name/start_preview websocket command that accepts flow_id, flow_type, and user_input, validates input, returns invalid_user_input on validation failure, and wires preview updates to the client.
Preview update semantics
docs/data_entry_flow_index.md
Specifies websocket callback messaging: sends {error: ...} for preview errors or {state, attributes, domain} for updates; validation errors return a websocket result with success: False.
Runtime preview entity (example)
docs/data_entry_flow_index.md
Provides an example PreviewSensorEntity with async_show_preview that computes state/attributes, invokes the preview callback, and converts ValueError into preview error callbacks.
Registration / Wiring (example)
docs/data_entry_flow_index.md
Shows adding a static async_setup_preview(hass) on the flow handler to register the websocket preview command and subscribe to previews.
Enablement & Frontend tip
docs/data_entry_flow_index.md
Demonstrates enabling previews by passing preview="..." to async_show_form and documents frontend fallback when domain is omitted from preview updates.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Data entry flow previews' directly and specifically describes the main change: adding documentation for data entry flow previews.
Description check ✅ Passed The PR description follows the required template, includes a clear proposed change, properly documents the type of change (existing features), completes the checklist, and provides detailed additional information with relevant links.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
docs/data_entry_flow_index.md (1)

603-619: ⚡ Quick win

Add missing imports/definitions or make them explicit placeholders.

Several identifiers used in the Step 1 snippet are not defined/imported within the snippet:

  • HomeAssistant, Any, Mapping
  • callback decorator
  • ConfigFlow, FlowType, SubentryFlowResult, ConfigEntry imports shown partially, but types used in function signature still rely on other symbols
  • PreviewSensorEntity depends on SensorEntity, CONF_DEVICE_CLASS, etc. (covered in Step 2, but Step 1 calls it)

If the intention is “illustrative pseudocode”, it should say so explicitly; otherwise readers will copy-paste and fail at runtime.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/data_entry_flow_index.md` around lines 603 - 619, The snippet is missing
several type and decorator definitions used in function signatures and classes;
either add explicit imports (e.g., import HomeAssistant from homeassistant.core,
Any/Mapping from typing, callback from homeassistant.core or
homeassistant.helpers.event, SensorEntity and CONF_DEVICE_CLASS from their
respective Home Assistant modules) and ensure
ConfigFlow/FlowType/SubentryFlowResult/ConfigEntry are fully imported where
referenced, or mark the whole block as illustrative pseudocode with a comment;
update references to PreviewSensorEntity to show it subclasses SensorEntity and
uses CONF_DEVICE_CLASS so readers know those dependencies must be imported or
stubbed before copying.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/data_entry_flow_index.md`:
- Around line 637-648: The docstring in async_preview_callback incorrectly
references _calculate_state; update the comment text to reference the async
method name _async_calculate_state (the method implemented/called by the Step 2
class) so readers implement the correct method; locate the doc comment inside
async_preview_callback and replace any mention of _calculate_state with
_async_calculate_state and ensure any explanatory text reflects that it is the
async method used for preview/state calculation.
- Around line 676-683: The constructor call for PreviewSensorEntity is
inconsistent with its definition and uses undefined variables: align
PreviewSensorEntity.__init__ and its instantiation by either updating the class
signature to def __init__(self, hass, value: str, config: dict[str, str]) ->
None or change the instantiation to pass the parameters the current __init__
expects; additionally, ensure value and config are defined before use (e.g.,
introduce explicit placeholder variables like value = "<preview_value>" and
config = {"key": "value"} in Step 1) so the call to PreviewSensorEntity(...) and
the async_show_preview subscription use valid, named variables.
- Around line 705-734: The async_show_preview callback has an off-by-one in
error truncation and an inconsistent callback parameter comment: in the except
block for async_show_preview (which calls _async_calculate_state and
preview_callback with CalculatedState values and self.domain), change the
truncation from error[:254] to error[:255] so errors capped at 255 chars are
preserved correctly, and update the preview_callback type comment from "errors"
to "error" to match the variable name used throughout; keep the existing
condition (if len(error) > 255) and ensure the final preview_callback(None,
None, error, None) remains unchanged.
- Around line 628-675: The snippet uses undefined variables cur_step and errors;
make the example self-contained by explicitly defining placeholders and showing
intent: add a cur_step placeholder (e.g., cur_step = flow_status["step"] or
cur_step = {"handler": ("<entry_id>", "<subflow>")} before using cur_step so
entry_id, _ = cur_step["handler"] resolves, and add an errors variable (e.g.,
errors: Mapping[str,str] | None = None or set errors from your validation logic)
before the if errors is not None check; include short comments indicating these
are placeholders to be replaced with real flow step lookup and validation
results (refer to symbols cur_step, flow_status, entry_id, errors,
async_preview_callback).

---

Nitpick comments:
In `@docs/data_entry_flow_index.md`:
- Around line 603-619: The snippet is missing several type and decorator
definitions used in function signatures and classes; either add explicit imports
(e.g., import HomeAssistant from homeassistant.core, Any/Mapping from typing,
callback from homeassistant.core or homeassistant.helpers.event, SensorEntity
and CONF_DEVICE_CLASS from their respective Home Assistant modules) and ensure
ConfigFlow/FlowType/SubentryFlowResult/ConfigEntry are fully imported where
referenced, or mark the whole block as illustrative pseudocode with a comment;
update references to PreviewSensorEntity to show it subclasses SensorEntity and
uses CONF_DEVICE_CLASS so readers know those dependencies must be imported or
stubbed before copying.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 24e149e9-0548-42ab-93d4-1a5dc25660c2

📥 Commits

Reviewing files that changed from the base of the PR and between d529960 and 610292d.

📒 Files selected for processing (1)
  • docs/data_entry_flow_index.md

Comment thread docs/data_entry_flow_index.md Outdated
Comment thread docs/data_entry_flow_index.md Outdated
Comment thread docs/data_entry_flow_index.md
Comment thread docs/data_entry_flow_index.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
docs/data_entry_flow_index.md (2)

698-698: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align PreviewSensorEntity constructor usage with class definition.

Line 698 passes hass into PreviewSensorEntity(...), but Line 720 defines __init__ without self and without hass; Line 722-723 also use config.get[...] instead of config.get(...).

Suggested patch
-    preview = PreviewSensorEntity(hass, preview_value=preview_value, config=config)
+    preview = PreviewSensorEntity(preview_value=preview_value, config=config)
@@
-    def __init__(preview_value: str, config: dict[str, str]) -> None:
+    def __init__(self, preview_value: str, config: dict[str, str]) -> None:
         self._attr_native_value = preview_value
-        self._attr_icon = config.get[ATTR_ICON]
-        self._attr_name = config.get[ATTR_NAME]
+        self._attr_icon = config.get(ATTR_ICON)
+        self._attr_name = config.get(ATTR_NAME)
         self._attr_device_class = config.get(CONF_DEVICE_CLASS)
         self._attr_native_unit_of_measurement = config.get(CONF_UNIT_OF_MEASUREMENT)
         self._attr_state_class = config.get(CONF_STATE_CLASS)
#!/bin/bash
# Verify constructor call/signature and config.get usage mismatch.
sed -n '697,725p' docs/data_entry_flow_index.md | nl -ba

Also applies to: 720-724

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/data_entry_flow_index.md` at line 698, The constructor call passes hass
(preview = PreviewSensorEntity(hass, preview_value=preview_value,
config=config)) but the class __init__ signature is defined incorrectly (missing
self and hass) and uses bracket indexing for config (config.get[...] instead of
config.get(...)); fix by updating PreviewSensorEntity.__init__ to include the
proper signature (def __init__(self, hass, preview_value=None, config=None):) or
remove hass from the constructor call to match the desired design, and replace
all occurrences of config.get[...] with config.get(...) so the config lookups
use method calls; ensure the symbol PreviewSensorEntity.__init__ and the
constructor call preview = PreviewSensorEntity(...) are consistent.

639-645: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Define cur_step before using it.

Line 644 reads cur_step["handler"] without defining cur_step, so the example is still not self-contained.

Suggested patch
     if msg["flow_type"] is FlowType.CONFIG_SUBENTRIES_FLOW:
         flow_status: SubentryFlowResult = hass.config_entries.subentries.async_get(msg["flow_id"])
         # TODO: get the config entry (if applicable or needed)
         # handler for subentry flow is a tuple of str of form
         # (entry_id, subentry_flow_type)
+        cur_step = flow_status["cur_step"]  # replace with the actual key/shape used
         entry_id, _ = cur_step["handler"]
         config_entry: ConfigEntry = hass.config_entries.async_get(entry_id)
#!/bin/bash
# Verify that cur_step is referenced before declaration in the snippet.
sed -n '636,646p' docs/data_entry_flow_index.md | nl -ba
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/data_entry_flow_index.md` around lines 639 - 645, The snippet uses
cur_step["handler"] before cur_step is defined; update the
FlowType.CONFIG_SUBENTRIES_FLOW branch to first obtain the current step (e.g.,
derive cur_step from flow_status or msg such as using flow_status.cur_step or
flow_status["steps"][...]) so cur_step is defined before accessing
cur_step["handler"]; ensure you reference the same flow_status from
hass.config_entries.subentries.async_get(msg["flow_id"]) and then extract
entry_id, _ = cur_step["handler"] and call
hass.config_entries.async_get(entry_id) to populate config_entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/data_entry_flow_index.md`:
- Around line 606-616: The snippet has invalid imports and dict syntax: change
the module import from homeassistant.config_entry to
homeassistant.config_entries and ensure commas separate imported names (e.g.,
after FlowType); also fix the constant imports to include commas between
ATTR_ICON and ATTR_NAME. In any example dict initialization shown (where keys
were written with =), replace assignment operators with proper dict key: value
pairs (use colons) and add any missing commas between entries; update the same
fixes for the repeated snippet around the later occurrence of the example (the
block referencing websocket_api,
ConfigEntry/ConfigFlow/FlowType/SubentryFlowResult, and ATTR_ICON/ATTR_NAME).

---

Duplicate comments:
In `@docs/data_entry_flow_index.md`:
- Line 698: The constructor call passes hass (preview =
PreviewSensorEntity(hass, preview_value=preview_value, config=config)) but the
class __init__ signature is defined incorrectly (missing self and hass) and uses
bracket indexing for config (config.get[...] instead of config.get(...)); fix by
updating PreviewSensorEntity.__init__ to include the proper signature (def
__init__(self, hass, preview_value=None, config=None):) or remove hass from the
constructor call to match the desired design, and replace all occurrences of
config.get[...] with config.get(...) so the config lookups use method calls;
ensure the symbol PreviewSensorEntity.__init__ and the constructor call preview
= PreviewSensorEntity(...) are consistent.
- Around line 639-645: The snippet uses cur_step["handler"] before cur_step is
defined; update the FlowType.CONFIG_SUBENTRIES_FLOW branch to first obtain the
current step (e.g., derive cur_step from flow_status or msg such as using
flow_status.cur_step or flow_status["steps"][...]) so cur_step is defined before
accessing cur_step["handler"]; ensure you reference the same flow_status from
hass.config_entries.subentries.async_get(msg["flow_id"]) and then extract
entry_id, _ = cur_step["handler"] and call
hass.config_entries.async_get(entry_id) to populate config_entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cae6d8df-753b-472e-b417-ada8964a2d9d

📥 Commits

Reviewing files that changed from the base of the PR and between 610292d and a4dd239.

📒 Files selected for processing (1)
  • docs/data_entry_flow_index.md

Comment thread docs/data_entry_flow_index.md
Comment thread docs/data_entry_flow_index.md Outdated
Clarify the usage of the 'domain' parameter in async_preview_callback and async_setup_preview.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/data_entry_flow_index.md`:
- Around line 710-711: Fix the duplicated word in the tip text for
async_preview_callback: update the sentence that currently reads "`domain` in
async_preview_callback refers to the the preview entity's domain..." by removing
the extra "the" so it reads "`domain` in async_preview_callback refers to the
preview entity's domain (e.g. \"sensor\" or \"select\"). If `domain` is not
provided or `None` the frontend will fallback to render a `SensorEntity` with
applicable attributes." Ensure the change is made to the doc string mentioning
async_preview_callback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 297a065e-1703-44ae-a28c-f3a2132c6082

📥 Commits

Reviewing files that changed from the base of the PR and between d05de95 and 4f12207.

📒 Files selected for processing (1)
  • docs/data_entry_flow_index.md

Comment thread docs/data_entry_flow_index.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
docs/data_entry_flow_index.md (4)

725-726: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix incorrect syntax for dict.get() method calls.

Lines 725-726 use square brackets config.get[...] instead of parentheses config.get(...). This is invalid syntax and will cause a runtime error.

🐛 Proposed fix
-        self._attr_icon = config.get[ATTR_ICON]
-        self._attr_name = config.get[ATTR_NAME]
+        self._attr_icon = config.get(ATTR_ICON)
+        self._attr_name = config.get(ATTR_NAME)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/data_entry_flow_index.md` around lines 725 - 726, The code uses invalid
square-bracket syntax for dict.get (config.get[ATTR_ICON] and
config.get[ATTR_NAME]); update both calls to use parentheses: call
config.get(ATTR_ICON) and config.get(ATTR_NAME) when assigning self._attr_icon
and self._attr_name so the dict.get method is invoked correctly.

722-722: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Add missing self parameter to __init__.

The __init__ method is missing the required self parameter as the first argument. This will cause a runtime error.

🐛 Proposed fix
-    def __init__(hass: HomeAssistant, preview_value: str, config: dict[str, str]) -> None:
+    def __init__(self, hass: HomeAssistant, preview_value: str, config: dict[str, str]) -> None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/data_entry_flow_index.md` at line 722, The __init__ signature shown is
missing the instance parameter; update the constructor for the class containing
__init__ so the first parameter is self (i.e., change def __init__(hass:
HomeAssistant, preview_value: str, config: dict[str, str]) -> None: to include
self as the first parameter). Locate the __init__ method in that class and add
self to the parameter list and adjust any internal references that currently
assume a different name accordingly.

653-656: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix missing commas in dictionary literal.

The dict literal is missing commas between key-value pairs, causing a syntax error.

🐛 Proposed fix
     config: dict[str, str] = {
-        ATTR_ICON: "mdi:eye"
-        ATTR_NAME: "Entity Preview"
+        ATTR_ICON: "mdi:eye",
+        ATTR_NAME: "Entity Preview",
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/data_entry_flow_index.md` around lines 653 - 656, The dictionary
assigned to the variable config (declared as config: dict[str, str]) is missing
commas between entries; update the literal so each key-value pair is separated
by a comma (i.e., add a comma after the ATTR_ICON: "mdi:eye" entry) so that
ATTR_ICON and ATTR_NAME entries form a valid dict with proper separators.

646-646: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix undefined variable cur_step.

Line 646 references cur_step["handler"] but cur_step is never defined. Only flow_status is defined (line 642). This makes the example non-functional.

🐛 Proposed fix
     if msg["flow_type"] is FlowType.CONFIG_SUBENTRIES_FLOW:
         flow_status: SubentryFlowResult = hass.config_entries.subentries.async_get(msg["flow_id"])
         # TODO: get the config entry (if applicable or needed)
         # handler for subentry flow is a tuple of str of form 
         # (entry_id, subentry_flow_type)
+        cur_step = flow_status["cur_step"]
         entry_id, _ = cur_step["handler"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/data_entry_flow_index.md` at line 646, The variable cur_step is
undefined; update the example to use the existing flow_status instead or define
cur_step before use. Replace the reference entry_id, _ = cur_step["handler"]
with entry_id, _ = flow_status["handler"] (or add cur_step = flow_status when
you want the alias) so the code reads from the defined flow_status object and
the example becomes functional.
🧹 Nitpick comments (2)
docs/data_entry_flow_index.md (2)

601-601: 💤 Low value

Improve opening phrase clarity.

The phrase "The below is specific to" is awkward. Use clearer wording.

Suggested revision
-The below is specific to `ConfigFlow` or `ConfigSubentryFlow` flows but is easily adaptable to an `OptionsFlow` or `RepairsFlow`.
+This example is specific to `ConfigFlow` or `ConfigSubentryFlow` flows but is easily adaptable to an `OptionsFlow` or `RepairsFlow`.

As per coding guidelines, apply the Microsoft Style Guide to maintain clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/data_entry_flow_index.md` at line 601, Replace the awkward opening
phrase "The below is specific to `ConfigFlow` or `ConfigSubentryFlow` flows but
is easily adaptable to an `OptionsFlow` or `RepairsFlow`." with a clearer
Microsoft-Style sentence such as "The following guidance applies to ConfigFlow
and ConfigSubentryFlow; it can also be adapted for OptionsFlow or RepairsFlow."
Update the text around the `ConfigFlow`, `ConfigSubentryFlow`, `OptionsFlow`,
and `RepairsFlow` symbols to match Microsoft Style Guide conventions (use "the
following" instead of "the below", remove redundant "flows" after named flow
types, and keep parallel structure).

597-597: 💤 Low value

Front the goal and use a more direct tone.

Per guidelines, instructional content should front the goal and avoid expressions like "you'll need to". Rewrite to front the action.

Suggested revision
-Currently preview entities are only supported for config entry flows, option flows, subentry config flows, and repair flows. To implement flow previews in a flow manager you'll need to complete the following basic steps:
+Preview entities are supported for config entry flows, option flows, subentry config flows, and repair flows. To implement flow previews in a flow manager, complete these steps:

As per coding guidelines, "In step-by-step instructions, front the 'goal' in the instructional sentence" and "use a direct and authoritative tone."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/data_entry_flow_index.md` at line 597, Rewrite the sentence that begins
"Currently preview entities are only supported for config entry flows, option
flows, subentry config flows, and repair flows." to front the goal and use a
direct tone; e.g. start with the action "Implement flow previews in a flow
manager by completing these basic steps:" and then follow with the list; replace
phrases like "you'll need to" with imperative wording so the sentence clearly
states the task ("Implement flow previews...") and retains the existing list of
supported flow types.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/data_entry_flow_index.md`:
- Around line 725-726: The code uses invalid square-bracket syntax for dict.get
(config.get[ATTR_ICON] and config.get[ATTR_NAME]); update both calls to use
parentheses: call config.get(ATTR_ICON) and config.get(ATTR_NAME) when assigning
self._attr_icon and self._attr_name so the dict.get method is invoked correctly.
- Line 722: The __init__ signature shown is missing the instance parameter;
update the constructor for the class containing __init__ so the first parameter
is self (i.e., change def __init__(hass: HomeAssistant, preview_value: str,
config: dict[str, str]) -> None: to include self as the first parameter). Locate
the __init__ method in that class and add self to the parameter list and adjust
any internal references that currently assume a different name accordingly.
- Around line 653-656: The dictionary assigned to the variable config (declared
as config: dict[str, str]) is missing commas between entries; update the literal
so each key-value pair is separated by a comma (i.e., add a comma after the
ATTR_ICON: "mdi:eye" entry) so that ATTR_ICON and ATTR_NAME entries form a valid
dict with proper separators.
- Line 646: The variable cur_step is undefined; update the example to use the
existing flow_status instead or define cur_step before use. Replace the
reference entry_id, _ = cur_step["handler"] with entry_id, _ =
flow_status["handler"] (or add cur_step = flow_status when you want the alias)
so the code reads from the defined flow_status object and the example becomes
functional.

---

Nitpick comments:
In `@docs/data_entry_flow_index.md`:
- Line 601: Replace the awkward opening phrase "The below is specific to
`ConfigFlow` or `ConfigSubentryFlow` flows but is easily adaptable to an
`OptionsFlow` or `RepairsFlow`." with a clearer Microsoft-Style sentence such as
"The following guidance applies to ConfigFlow and ConfigSubentryFlow; it can
also be adapted for OptionsFlow or RepairsFlow." Update the text around the
`ConfigFlow`, `ConfigSubentryFlow`, `OptionsFlow`, and `RepairsFlow` symbols to
match Microsoft Style Guide conventions (use "the following" instead of "the
below", remove redundant "flows" after named flow types, and keep parallel
structure).
- Line 597: Rewrite the sentence that begins "Currently preview entities are
only supported for config entry flows, option flows, subentry config flows, and
repair flows." to front the goal and use a direct tone; e.g. start with the
action "Implement flow previews in a flow manager by completing these basic
steps:" and then follow with the list; replace phrases like "you'll need to"
with imperative wording so the sentence clearly states the task ("Implement flow
previews...") and retains the existing list of supported flow types.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa090a0c-e0ac-480e-99ed-39c085d081df

📥 Commits

Reviewing files that changed from the base of the PR and between 4f12207 and 18d4a97.

📒 Files selected for processing (1)
  • docs/data_entry_flow_index.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new developer documentation describing how to implement “entity previews” in Home Assistant data entry flows, including a websocket endpoint and a preview entity example to drive live UI updates.

Changes:

  • Documented support scope and step-by-step setup for data entry flow entity previews.
  • Added an end-to-end Python example for a preview websocket command + forwarding preview updates to the frontend.
  • Added an example preview entity implementation and how to wire it up via async_setup_preview and async_show_form(preview=...).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/data_entry_flow_index.md
Comment thread docs/data_entry_flow_index.md
Comment thread docs/data_entry_flow_index.md Outdated
Comment thread docs/data_entry_flow_index.md Outdated
Comment thread docs/data_entry_flow_index.md Outdated
Comment thread docs/data_entry_flow_index.md Outdated
Comment thread docs/data_entry_flow_index.md Outdated
Comment thread docs/data_entry_flow_index.md
Comment thread docs/data_entry_flow_index.md Outdated
# handler for subentry flow is a tuple of str of form
# (entry_id, subentry_flow_type)
entry_id, _ = flow_status["handler"]
config_entry: ConfigEntry = hass.config_entries.async_get(entry_id)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
config_entry: ConfigEntry = hass.config_entries.async_get(entry_id)
config_entry: ConfigEntry = hass.config_entries.async_get_entry(entry_id)

Looks like a method name mistake

Comment thread docs/data_entry_flow_index.md Outdated
self._attr_state_class = config.get(CONF_STATE_CLASS)

@callback
def async_show_preview(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why async_show_preview and async_preview_callback? The existing integrations use async_start_preview and async_preview_updated

Comment thread docs/data_entry_flow_index.md Outdated

@websocket_api.websocket_command(
{
vol.Required("type"): "preview_name/start_preview", # "preview_name" corresponds to the value in async_show_form(..., preview="preview_name") and needs to be unique so use something like f"{DOMAIN}_my_flow_handler"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that the frontend doesn't support generic previews but needs to add support for each new type of flow? If that's the case I'm wondering if we should document this at all, since it's not a generic interface.

@iluvdata iluvdata May 22, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frontend does support generic previews.

@MindFreeze as well:
I was inspired to create this documentation as I created a flow preview in a custom integration (that I'll be adding to the core in the next few months) because it was such an onerous process to figure this out and as you can see it takes a lot of code to get it working! That said we probably don't want developers adding this amount of code to a core integration for review efficiency purposes.

Let's leave this as a draft. I'll post something on the community forum in the meantime and I'll start thinking about how to create reusable helper code in homeassistant.helpers.data_entry_flow that will make any future preview code easier to create, test and review.

@MartinHjelmare
MartinHjelmare marked this pull request as draft May 22, 2026 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants