Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MVP voice assist flow #22061

Merged
merged 4 commits into from
Sep 24, 2024
Merged

Add MVP voice assist flow #22061

merged 4 commits into from
Sep 24, 2024

Conversation

bramkragten
Copy link
Member

@bramkragten bramkragten commented Sep 23, 2024

Proposed change

Adds an MVP voice assist setup flow.

Copy needs to be updated (and translated if final)

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (thank you!)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Example configuration

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue or discussion:
  • Link to documentation pull request:

Checklist

  • The code change is tested and works locally.
  • There is no commented out code in this PR.
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a voice assistant setup dialog for streamlined configuration.
    • Added functionality for managing wake words and voice assistant pipelines.
    • Users can now select areas and wake words during the setup process.
    • Enhanced device configuration page with a direct "Set up voice assistant" action.
    • New methods for intercepting wake words and testing assistive satellite connections.
    • Added a component for managing the update process of the voice assistant.
  • Bug Fixes

    • Improved error handling and conditional rendering in voice assistant pipeline details.
  • Style

    • New styles for voice assistant setup components to enhance user experience.
  • Documentation

    • Updated interfaces to support new optional properties for better flexibility in voice assistant configurations.

Copy link
Contributor

coderabbitai bot commented Sep 23, 2024

Walkthrough

Walkthrough

The changes introduce a comprehensive voice assistant setup process within a Home Assistant environment. This includes the addition of interfaces for managing wake words, several functions for interacting with the assistive satellite system, and enhancements to the device configuration page that facilitate direct initiation of the voice assistant setup for devices associated with the "assist_satellite" domain. A new component for managing the update process of the voice assistant is also included.

Changes

Files Change Summary
src/data/assist_satellite.ts Introduced interfaces for wake word management and several functions for interacting with the assistive satellite system, including interceptWakeWord, testAssistSatelliteConnection, and setWakeWords.
src/dialogs/config-flow/step-flow-create-entry.ts Added a private method _deviceEntities to optimize filtering of entity registry entries based on device ID, enhancing user experience when a single device is present.
src/panels/config/devices/ha-config-device-page.ts Enhanced the HaConfigDevicePage class to include a new action for setting up a voice assistant if associated entities belong to the "assist_satellite" domain.
src/dialogs/voice-assistant-setup/voice-assistant-setup-step-update.ts Introduced a new LitElement component for managing the update process of a voice assistant, including properties for Home Assistant instance and update entity ID, lifecycle methods for handling updates, and a UI for displaying the update progress.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DevicePage
    participant VoiceAssistantSetupDialog
    participant UpdateComponent

    User->>DevicePage: Initiate voice assistant setup
    DevicePage->>VoiceAssistantSetupDialog: Show setup dialog
    VoiceAssistantSetupDialog->>User: Display setup steps
    User->>VoiceAssistantSetupDialog: Select wake word
    VoiceAssistantSetupDialog->>VoiceAssistantSetupDialog: Update configuration
    VoiceAssistantSetupDialog->>User: Confirm setup success
    User->>UpdateComponent: Trigger update process
    UpdateComponent->>UpdateComponent: Check entity state
    UpdateComponent->>User: Display update progress
    UpdateComponent->>User: Confirm update success
Loading

Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8714157 and 570cf7f.

Files selected for processing (1)
  • src/dialogs/config-flow/step-flow-create-entry.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/dialogs/config-flow/step-flow-create-entry.ts

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 33

Outside diff range and nitpick comments (22)
src/dialogs/voice-assistant-setup/show-voice-assistant-setup-dialog.ts (3)

3-4: LGTM: Good use of dynamic import.

The loadVoiceAssistantSetupDialog function uses dynamic import, which is excellent for code splitting and lazy loading. This approach can improve initial load times by deferring the loading of the dialog component until it's needed.

Consider adding a type annotation to the function for improved clarity:

const loadVoiceAssistantSetupDialog = (): Promise<typeof import("./voice-assistant-setup-dialog")> =>
  import("./voice-assistant-setup-dialog");

6-8: LGTM: Clear and concise interface definition.

The VoiceAssistantSetupDialogParams interface is well-defined and exported, which promotes type safety when used across the application.

Consider adding a JSDoc comment to provide more context about the interface and its usage:

/**
 * Parameters for initializing the voice assistant setup dialog.
 */
export interface VoiceAssistantSetupDialogParams {
  /** The ID of the device for which the voice assistant is being set up. */
  deviceId: string;
}

10-19: LGTM: Well-structured dialog show function.

The showVoiceAssistantSetupDialog function is well-implemented, using a custom event to trigger the dialog display. This approach allows for loose coupling between components and supports lazy loading of the dialog component.

Consider adding a JSDoc comment to provide more context about the function and its parameters:

/**
 * Shows the voice assistant setup dialog.
 * @param element - The HTML element on which to dispatch the event.
 * @param dialogParams - The parameters for the dialog.
 */
export const showVoiceAssistantSetupDialog = (
  element: HTMLElement,
  dialogParams: VoiceAssistantSetupDialogParams
): void => {
  // ... (existing implementation)
};
src/dialogs/voice-assistant-setup/styles.ts (1)

6-35: LGTM: Well-structured and responsive CSS styles.

The CSS styles are well-organized, use flexbox appropriately for layout, and provide good responsiveness. The component-specific styling reduces the risk of unintended side effects.

Consider adding a media query for larger screens to adjust the max-width of the host element. This could improve readability on desktop devices. For example:

@media (min-width: 600px) {
  :host {
    max-width: 600px;
  }
}
src/panels/config/voice-assistants/show-dialog-voice-assistant-pipeline-detail.ts (1)

11-11: LGTM! Consider adding documentation for the new property.

The addition of the optional hideWakeWord property is a good approach to control the visibility of the wake word feature in the UI. It aligns well with the MVP voice assist flow objectives.

Consider adding a brief comment explaining the purpose and usage of this property to improve code maintainability.

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-cloud.ts (1)

8-9: Consider adding a description for the component

The class declaration and property look correct. However, it would be beneficial to add a JSDoc comment describing the purpose and usage of this component.

Consider adding a description like this:

/**
 * A component for setting up Home Assistant Cloud for voice assistants.
 * This step promotes the benefits of using Home Assistant Cloud and provides a link to start a free trial.
 */
@customElement("ha-voice-assistant-setup-step-cloud")
export class HaVoiceAssistantSetupStepCloud extends LitElement {
  // ... rest of the code
}
src/data/assist_satellite.ts (5)

7-11: LGTM: Well-structured interface for wake word options.

The WakeWordOption interface clearly represents a wake word option with its identifier, the wake word itself, and the languages it's trained in.

Consider using a more specific type for trained_languages to enhance type safety:

trained_languages: readonly string[];

This change would prevent accidental modifications to the array and better represent its intended use as a read-only list of languages.


13-19: LGTM: Comprehensive interface for assist satellite configuration.

The AssistSatelliteConfiguration interface provides a clear and complete representation of the assist satellite configuration.

Consider using readonly properties to enhance type safety and prevent accidental modifications:

export interface AssistSatelliteConfiguration {
  readonly active_wake_words: readonly string[];
  readonly available_wake_words: readonly WakeWordOption[];
  readonly max_active_wake_words: number;
  readonly pipeline_entity_id: string;
  readonly vad_entity_id: string;
}

This change would better represent the configuration as an immutable object.


21-29: LGTM: Well-implemented function for intercepting wake words.

The interceptWakeWord function correctly sets up a subscription for wake word interception messages.

Consider adding a return type to the function for improved type safety:

export const interceptWakeWord = (
  hass: HomeAssistant,
  entity_id: string,
  callback: (result: WakeWordInterceptMessage) => void
): Promise<() => Promise<void>> => // Add this return type
  hass.connection.subscribeMessage(callback, {
    type: "assist_satellite/intercept_wake_word",
    entity_id,
  });

This change would make it clear that the function returns a Promise that resolves to an unsubscribe function.


42-47: LGTM: Well-implemented function for sending announcements to the assist satellite.

The assistSatelliteAnnounce function correctly uses the callService method to send an announcement to the assist satellite.

For consistency with other functions in this file, consider adding a return type:

export const assistSatelliteAnnounce = (
  hass: HomeAssistant,
  entity_id: string,
  message: string
): Promise<void> => // Add this return type
  hass.callService("assist_satellite", "announce", { message }, { entity_id });

This change would make it clear that the function returns a Promise that resolves when the service call is complete.


58-67: LGTM: Well-implemented function for setting wake words.

The setWakeWords function correctly uses the WebSocket API to update the active wake words for a specified entity.

Consider adding a return type and using a readonly array for wake_word_ids to enhance type safety:

export const setWakeWords = (
  hass: HomeAssistant,
  entity_id: string,
  wake_word_ids: readonly string[]
): Promise<void> => // Add this return type
  hass.callWS({
    type: "assist_satellite/set_wake_words",
    entity_id,
    wake_word_ids,
  });

These changes would prevent accidental modifications to the wake_word_ids array and make it clear that the function returns a Promise that resolves when the operation is complete.

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-change-wake-word.ts (1)

23-46: Render method looks good, but there's a typo in the description.

The render method is well-structured, combining static content with dynamic rendering of wake words. However, there's a typo in the description:

- When you voice assistant knows where it is, it can better control the
+ When your voice assistant knows where it is, it can better control the

Please correct this typo to improve the user experience.

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-check.ts (1)

10-14: LGTM: Properties and state are well-defined. Consider adding JSDoc comments.

The properties and state are correctly defined and typed. However, adding JSDoc comments for each property and state would improve code readability and maintainability.

Consider adding JSDoc comments for each property and state. For example:

/**
 * The Home Assistant instance
 */
@property({ attribute: false }) public hass!: HomeAssistant;

/**
 * The entity ID of the assist satellite
 */
@property() public assistEntityId?: string;

/**
 * The current status of the connection test
 */
@state() private _status?: "success" | "timeout";
src/dialogs/voice-assistant-setup/voice-assistant-setup-step-addons.ts (1)

13-35: Consider using constants for timeout values.

The use of state properties and the staggered reveal effect in firstUpdated is good for user experience. However, the hard-coded timeout values might make it difficult to adjust timing in the future.

Consider defining constants for these timeout values at the top of the file:

const FIRST_MESSAGE_DELAY = 200;
const SECOND_MESSAGE_DELAY = 600;
const THIRD_MESSAGE_DELAY = 3000;
const FOURTH_MESSAGE_DELAY = 8000;

Then use these constants in the firstUpdated method:

setTimeout(() => {
  this._showFirst = true;
}, FIRST_MESSAGE_DELAY);
// ... and so on for the other timeouts

This will make it easier to adjust timing in the future if needed.

src/panels/config/voice-assistants/dialog-voice-assistant-pipeline-detail.ts (2)

218-225: LGTM! Consider extracting the condition for improved readability.

The conditional rendering of the assist-pipeline-detail-wakeword component is well-implemented. It provides flexibility in the UI by allowing the wake word configuration to be optionally hidden.

For improved readability, consider extracting the condition into a separate constant:

const showWakeWord = !this._params.hideWakeWord;

${showWakeWord
  ? html`<assist-pipeline-detail-wakeword
      .hass=${this.hass}
      .data=${this._data}
      keys="wake_word_entity,wake_word_id"
      @value-changed=${this._valueChanged}
    ></assist-pipeline-detail-wakeword>`
  : nothing}

This change would make the template easier to read and the condition's purpose more explicit.


Line range hint 1-369: Consider implementing a consistent error handling strategy.

The recent changes have improved error handling in several places, which is great. To further enhance the robustness and user experience of the component, consider implementing a consistent error handling strategy throughout the class.

Here are some suggestions:

  1. Create a dedicated method for setting errors:
private _setError(error: Error | string) {
  this._error = typeof error === "string" ? error : error.message || "Unknown error";
  this._submitting = false;
}
  1. Use this method consistently in all catch blocks:
} catch (err: any) {
  this._setError(err);
}
  1. Ensure all user actions that can fail (update, create, delete, set preferred) use try-catch blocks with this error handling.

  2. Consider adding a method to clear errors when appropriate, such as when the dialog is opened or closed.

These changes would provide a more consistent and maintainable approach to error handling throughout the component.

src/panels/config/devices/ha-config-device-page.ts (2)

1067-1080: New voice assistant setup action added

A new condition has been added to check if any of the device's entities belong to the "assist_satellite" domain. If true, a new action for setting up the voice assistant is added to the deviceActions array.

This implementation aligns with the PR objective and provides a way for users to initiate the voice assistant setup directly from the device page.

However, consider adding a comment explaining the purpose of this check and action for better code readability.

Consider adding a comment like:

// Add voice assistant setup action for devices with assist_satellite entities

1415-1419: New _voiceAssistantSetup method

A new private method _voiceAssistantSetup has been added to handle the voice assistant setup action. It calls the showVoiceAssistantSetupDialog function with the current device ID.

This implementation is correct and aligns with the PR objective.

Consider adding a JSDoc comment to describe the purpose of this method.

Add a JSDoc comment like:

/**
 * Initiates the voice assistant setup dialog for the current device.
 */
src/dialogs/voice-assistant-setup/voice-assistant-setup-step-update.ts (2)

58-60: Safeguard division operation to prevent NaN results

When calculating the progress value, dividing by 100 without ensuring stateObj.attributes.in_progress is a valid number can result in NaN if the value is undefined. It's prudent to provide a default value to avoid this issue.

Apply this diff to provide a default value:

.value=${progressIsNumeric
-   ? stateObj.attributes.in_progress / 100
+   ? (stateObj.attributes.in_progress || 0) / 100
    : undefined}

77-81: Simplify state check by using updateEntity.state directly

In the _tryUpdate method, you can simplify the state check by accessing updateEntity.state directly, since updateEntity already contains the entity's state. This improves code readability and efficiency.

Apply this diff to simplify the code:

if (
  updateEntity &&
-   this.hass.states[updateEntity.entity_id].state === "on"
+   updateEntity.state === "on"
) {
src/dialogs/voice-assistant-setup/voice-assistant-setup-step-wake-word.ts (1)

68-68: Localize user-facing strings using this.hass.localize

The strings displayed to the user should be localized to support multiple languages.

Apply this diff to localize the strings:

 <!-- In line 68 -->
-<img src="/static/icons/casita/sleeping.png" />
+<img
+  src="/static/icons/casita/sleeping.png"
+  alt="${this.hass.localize('ui.dialogs.voice_assistant_setup.icon_sleeping_alt')}"
+/>

 <!-- In lines 70-73 -->
-<h1>
-  Say “${this._activeWakeWord(this.assistConfiguration)}” to wake the
-  device up
-</h1>
+<h1>
+  ${this.hass.localize(
+    "ui.dialogs.voice_assistant_setup.say_to_wake_device",
+    "wake_word",
+    this._activeWakeWord(this.assistConfiguration)
+  )}
+</h1>
-<p class="secondary">Setup will continue once the device is awake.</p>
+<p class="secondary">
+  ${this.hass.localize("ui.dialogs.voice_assistant_setup.setup_will_continue")}
+</p>

 <!-- In line 75 -->
-<img src="/static/icons/casita/normal.png" />
+<img
+  src="/static/icons/casita/normal.png"
+  alt="${this.hass.localize('ui.dialogs.voice_assistant_setup.icon_normal_alt')}"
+/>

 <!-- In lines 77-81 -->
-<h1>
-  Say “${this._activeWakeWord(this.assistConfiguration)}” again
-</h1>
-<p class="secondary">
-  To make sure the wake word works for you.
-</p>
+<h1>
+  ${this.hass.localize(
+    "ui.dialogs.voice_assistant_setup.say_again",
+    "wake_word",
+    this._activeWakeWord(this.assistConfiguration)
+  )}
+</h1>
+<p class="secondary">
+  ${this.hass.localize("ui.dialogs.voice_assistant_setup.wake_word_works_for_you")}
+</p>

 <!-- In line 84 -->
-<ha-button @click=${this._changeWakeWord}>Change wake word</ha-button>
+<ha-button @click=${this._changeWakeWord}>
+  ${this.hass.localize("ui.dialogs.voice_assistant_setup.change_wake_word")}
+</ha-button>

Ensure that the localization keys are added to the translation files.

Also applies to: 70-73, 75-75, 77-81, 84-84

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-success.ts (1)

15-17: Remove unused import 'assistSatelliteAnnounce'

The function assistSatelliteAnnounce is imported but not used in this file. Removing unused imports helps keep the codebase clean and can improve build times.

Apply this diff to remove the unused import:

- import {
-   assistSatelliteAnnounce,
-   AssistSatelliteConfiguration,
- } from "../../data/assist_satellite";
+ import {
+   AssistSatelliteConfiguration,
+ } from "../../data/assist_satellite";
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between af46b82 and 163ecd6.

Files ignored due to path filters (6)
  • public/static/icons/casita/loading.png is excluded by !**/*.png
  • public/static/icons/casita/loving.png is excluded by !**/*.png
  • public/static/icons/casita/normal.png is excluded by !**/*.png
  • public/static/icons/casita/sad.png is excluded by !**/*.png
  • public/static/icons/casita/sleeping.png is excluded by !**/*.png
  • public/static/icons/casita/smiling.png is excluded by !**/*.png
Files selected for processing (17)
  • src/data/assist_satellite.ts (1 hunks)
  • src/dialogs/config-flow/step-flow-create-entry.ts (3 hunks)
  • src/dialogs/voice-assistant-setup/show-voice-assistant-setup-dialog.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/styles.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-dialog.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-addons.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-area.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-change-wake-word.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-check.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-cloud.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-pipeline.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-success.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-update.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-wake-word.ts (1 hunks)
  • src/panels/config/devices/ha-config-device-page.ts (4 hunks)
  • src/panels/config/voice-assistants/dialog-voice-assistant-pipeline-detail.ts (3 hunks)
  • src/panels/config/voice-assistants/show-dialog-voice-assistant-pipeline-detail.ts (1 hunks)
Additional context used
Biome
src/dialogs/voice-assistant-setup/voice-assistant-setup-dialog.ts

[error] 28-39: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

Additional comments not posted (34)
src/dialogs/voice-assistant-setup/show-voice-assistant-setup-dialog.ts (2)

1-1: LGTM: Import statement is appropriate.

The import of fireEvent from the common module is suitable for the file's purpose of triggering custom events.


1-19: Overall: Excellent implementation of the voice assistant setup dialog launcher.

This file provides a clean and efficient implementation for launching the voice assistant setup dialog. It aligns well with the PR objectives of adding an MVP voice assist flow to the Home Assistant frontend. The use of TypeScript, dynamic imports, and custom events demonstrates good modern web development practices.

Key strengths:

  1. Clear separation of concerns
  2. Type safety with exported interface
  3. Lazy loading of dialog component
  4. Loose coupling through custom events

The suggested minor improvements (adding JSDoc comments and type annotations) would further enhance the code's readability and maintainability, but the current implementation is already of high quality.

src/dialogs/voice-assistant-setup/styles.ts (3)

1-2: LGTM: Imports are correct and appropriate.

The imports for css from "lit" and haStyle from the relative path are correctly implemented and necessary for the file's functionality.


4-5: LGTM: Export declaration is well-structured.

The export of AssistantSetupStyles as an array containing haStyle and custom CSS is a good approach. It allows for easy composition of styles and ensures consistency with the overall Home Assistant styling.


1-36: Overall: Excellent implementation of styles for the voice assistant setup.

This new file provides a solid foundation for styling the voice assistant setup component. The code is well-structured, follows best practices, and aligns well with the PR objectives. The use of flexbox for layout ensures good responsiveness, and the styles are appropriately scoped to the component.

The implementation demonstrates attention to detail in creating a user-friendly interface for the MVP voice assist flow. Great job!

src/panels/config/voice-assistants/show-dialog-voice-assistant-pipeline-detail.ts (2)

11-15: Overall, the changes look good and align with the PR objectives.

The modifications to the VoiceAssistantPipelineDetailsDialogParams interface enhance its flexibility, which is beneficial for the MVP voice assist flow. The new hideWakeWord property and the optional createPipeline and deletePipeline properties provide more control over the UI and pipeline management.

To ensure a smooth integration:

  1. Consider adding brief documentation for the hideWakeWord property.
  2. Verify that existing code handles the now-optional createPipeline and deletePipeline properties correctly.

These changes lay a good foundation for the voice assistant setup process in the Home Assistant frontend.


15-15: LGTM! Verify existing usage of deletePipeline.

Making deletePipeline optional provides more flexibility in the interface usage, which aligns well with the MVP voice assist flow objectives.

Please ensure that existing code handles the case where deletePipeline might be undefined. Run the following script to check its usage:

#!/bin/bash
# Description: Check usage of deletePipeline in the codebase

# Search for deletePipeline usage
rg --type typescript -A 5 'deletePipeline'
src/dialogs/voice-assistant-setup/voice-assistant-setup-step-cloud.ts (4)

1-7: LGTM: Imports and decorators look good

The imports and decorators are correctly implemented. The use of customElement decorator for defining the custom element is a good practice.


27-29: LGTM: Close method is correctly implemented

The _close method is simple and correctly implemented. It fires a "closed" event, which is likely used by the parent component to handle the closing of this setup step.


34-38: LGTM: Global declaration is correctly implemented

The global declaration for the custom element is correctly implemented. This ensures proper TypeScript support when using this custom element in HTML.


1-38: Overall assessment: Good implementation with room for improvement

The HaVoiceAssistantSetupStepCloud component is well-structured and follows LitElement best practices. It successfully introduces a new step in the voice assistant setup process, promoting Home Assistant Cloud.

Key strengths:

  1. Proper use of LitElement and its decorators.
  2. Clear separation of concerns between rendering and event handling.

Areas for improvement:

  1. Enhance accessibility by adding alt text to images and avoiding nested interactive elements.
  2. Implement internationalization for better multi-language support.
  3. Consider adding JSDoc comments for better documentation.
  4. Refine the styling approach for better encapsulation.

These improvements will make the component more robust, accessible, and easier to maintain in the long run.

src/data/assist_satellite.ts (4)

3-5: LGTM: Well-defined interface for wake word interception.

The WakeWordInterceptMessage interface is concise and clearly represents the structure of a wake word intercept message.


31-40: LGTM: Well-implemented function for testing assist satellite connection.

The testAssistSatelliteConnection function correctly uses the WebSocket API to test the connection status of the assist satellite. The return type is properly specified, ensuring type safety for the response.


49-56: LGTM: Well-implemented function for fetching assist satellite configuration.

The fetchAssistSatelliteConfiguration function correctly uses the WebSocket API to retrieve the current configuration of the assist satellite. The return type is properly specified using the AssistSatelliteConfiguration interface, ensuring type safety for the response.


1-67: Overall: Excellent implementation of assist satellite data management.

This file provides a comprehensive set of interfaces and functions for managing wake words and configurations in an assist satellite system. The code is well-structured, follows TypeScript conventions, and demonstrates good use of type safety. The minor suggestions provided in the review comments will further enhance the robustness of the code.

Great job on implementing this new feature!

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-area.ts (5)

1-9: LGTM: Imports and decorators are appropriate.

The imports and decorators are well-structured and follow Home Assistant conventions for LitElement components.


10-13: LGTM: Class definition and properties are well-defined.

The class extends LitElement correctly, and the properties are appropriately decorated and typed. The hass property is correctly marked as non-attribute.


35-49: LGTM: Utility methods are well-implemented.

The _setArea and _nextStep methods handle their responsibilities correctly. Error handling is present, and the use of updateDeviceRegistryEntry and fireEvent is appropriate.


51-67: LGTM: Styles and global declaration are correct.

The styles are appropriately defined, combining imported styles with additional CSS. The global declaration for HTMLElementTagNameMap is correctly implemented, ensuring TypeScript recognition of the custom element.


15-33: LGTM: Render method structure is appropriate.

The render method creates a logical UI structure for a setup step, including an image, header, description, area picker, and a button.

Please verify the existence of the static asset:

Verification successful

Static asset loving.png exists as expected.

The asset loving.png was found at public/static/icons/casita/loving.png, confirming that the path /static/icons/casita/loving.png in the code is valid.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence of the loving.png asset
fd -t f "loving.png" static/icons/casita

Length of output: 147


Script:

#!/bin/bash
# Check if the static/icons directory exists
if [ -d "static/icons" ]; then
  echo "static/icons directory exists."
else
  echo "static/icons directory does not exist."
  exit 1
fi

# Search for loving.png within the static/icons directory
fd -t f "loving.png" static/icons

Length of output: 121


Script:

#!/bin/bash
# Search for loving.png throughout the entire codebase
fd -t f "loving.png"

Length of output: 58

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-change-wake-word.ts (3)

1-12: Imports look good and are well-organized.

The necessary modules and types are imported correctly, and there are no unused imports. The import order is logical, starting with external libraries followed by internal modules.


14-21: Class definition and properties are well-structured.

The class is correctly defined as a custom element extending LitElement. The properties are appropriately decorated and typed, with hass being required and the others optional. This structure provides good flexibility for the component's usage.


63-84: Styles and global declaration are appropriate.

The use of AssistantSetupStyles promotes consistency, and the additional custom CSS for padding and list styling is well-defined. The global declaration correctly maps the custom element name to its class, which is necessary for TypeScript type checking.

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-check.ts (2)

1-9: LGTM: Imports and class declaration are well-structured.

The imports are appropriate for a LitElement component, and the custom element declaration follows the Home Assistant naming convention.


80-87: LGTM: Styles and global declaration are correctly implemented.

The use of shared AssistantSetupStyles promotes consistency, and the global declaration follows TypeScript best practices for custom elements.

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-addons.ts (1)

1-11: LGTM: Imports and class declaration are well-structured.

The imports are appropriate for a LitElement component, and the class declaration follows best practices with proper decorators and typing.

src/panels/config/devices/ha-config-device-page.ts (2)

8-8: New import for voice assistant setup dialog

A new import statement has been added for the showVoiceAssistantSetupDialog function. This is consistent with the PR objective of adding an MVP voice assist flow.


Line range hint 8-1419: Overall assessment of voice assistant setup changes

The changes introduced for the voice assistant setup functionality are well-implemented and align with the PR objective. The new import, condition check in _getDeviceActions, and the _voiceAssistantSetup method work together to provide a seamless way for users to initiate the voice assistant setup for compatible devices.

A few minor suggestions have been made to improve code documentation, but these are not critical issues. The implementation is approved and ready for integration.

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-update.ts (2)

95-98: Ensure updateConfig is correctly set when no update occurs

In the _nextStep method, the updateConfig property is set based on _updated. If _tryUpdate doesn't result in an update, _updated remains false. Confirm that this behavior aligns with the desired logic for progressing to the next step.


1-116: Overall implementation aligns with best practices

The component is well-structured, following LitElement conventions. Properties and state management are handled appropriately, and the user interface provides clear feedback during the update process.

src/dialogs/config-flow/step-flow-create-entry.ts (2)

52-56: Ensure proper sequencing after _flowDone()

After calling this._flowDone(), make sure that the component's state updates as expected before showing the voice assistant setup dialog. If _flowDone() leads to unmounting or state changes, the subsequent call to showVoiceAssistantSetupDialog may not behave as intended.


48-50: Confirm the correctness of the domain comparison

When checking if an entity belongs to the assist_satellite domain using computeDomain(entity.entity_id) === "assist_satellite", verify that assist_satellite is the correct domain name and that computeDomain will return it as expected. Domains are typically things like sensor, light, etc.

You can run the following script to list all entities with the assist_satellite domain:

src/dialogs/voice-assistant-setup/voice-assistant-setup-step-success.ts (2)

178-182: Validate 'preferred_pipeline' before comparison

In the _openPipeline method, preferred_pipeline might be undefined, which can cause issues when comparing it to pipeline.id.

Modify the comparison to handle undefined preferred_pipeline:

preferred: preferred_pipeline
  ? pipeline.id === preferred_pipeline
  : false,

Likely invalid or redundant comment.


201-203: Confirm event name in '_close' method

Ensure that the event 'closed' fired in the _close method is the correct event name expected by the parent component.

Run the following script to verify event listeners for 'closed':

Comment on lines +11 to +25
protected override render() {
return html`<div class="content">
<img src="/static/icons/casita/loving.png" />
<h1>Home Assistant Cloud</h1>
<p class="secondary">
With Home Assistant Cloud, you get the best results for your voice
assistant, sign up for a free trial now.
</p>
</div>
<div class="footer">
<a href="/config/cloud/register" @click=${this._close}
><ha-button>Start your free trial</ha-button></a
>
</div>`;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Render method: Consider accessibility and internationalization

The render method looks functional, but there are a few areas for improvement:

  1. The image should have an alt attribute for accessibility.
  2. The text content should be internationalized for multi-language support.
  3. The <a> tag wrapping the button might lead to nested interactive elements, which is not ideal for accessibility.

Consider applying these changes:

  1. Add an alt attribute to the image:
- <img src="/static/icons/casita/loving.png" />
+ <img src="/static/icons/casita/loving.png" alt="Home Assistant Cloud" />
  1. Use localization for text content:
- <h1>Home Assistant Cloud</h1>
+ <h1>${this.hass.localize("ui.panel.config.cloud.register.title")}</h1>
- <p class="secondary">
-   With Home Assistant Cloud, you get the best results for your voice
-   assistant, sign up for a free trial now.
- </p>
+ <p class="secondary">
+   ${this.hass.localize("ui.dialogs.voice_assistant.cloud_promo")}
+ </p>
- <ha-button>Start your free trial</ha-button>
+ <ha-button>${this.hass.localize("ui.dialogs.voice_assistant.start_free_trial")}</ha-button>
  1. Replace the <a> tag with an event handler on the button:
- <a href="/config/cloud/register" @click=${this._close}>
-   <ha-button>Start your free trial</ha-button>
- </a>
+ <ha-button @click=${this._startFreeTrial}>
+   ${this.hass.localize("ui.dialogs.voice_assistant.start_free_trial")}
+ </ha-button>

Then add a new method to handle the button click:

private _startFreeTrial() {
  this._close();
  this.hass.navigate("/config/cloud/register");
}

This approach separates the navigation logic from the UI event, which is a better practice.

fireEvent(this, "closed");
}

static styles = AssistantSetupStyles;
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider defining styles within the class

While using a shared style is not incorrect, it might be beneficial to define specific styles within the class for better encapsulation and easier maintenance.

Consider defining the styles within the class like this:

static get styles() {
  return [
    AssistantSetupStyles,
    css`
      // Add any component-specific styles here
    `
  ];
}

This approach allows you to extend the shared styles with component-specific styles if needed in the future.

Comment on lines +22 to +23
When you voice assistant knows where it is, it can better control the
devices around it.
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix typo in the description text.

There's a small typo in the description text.

Apply this diff to fix the typo:

-          When you voice assistant knows where it is, it can better control the
+          When your voice assistant knows where it is, it can better control the
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
When you voice assistant knows where it is, it can better control the
devices around it.
When your voice assistant knows where it is, it can better control the
devices around it.

Comment on lines +48 to +57
private async _wakeWordPicked(ev) {
if (!this.assistEntityId) {
return;
}

const wakeWordId = ev.currentTarget.value;

await setWakeWords(this.hass, this.assistEntityId, [wakeWordId]);
this._nextStep();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding error handling in _wakeWordPicked method.

The method correctly checks for the existence of assistEntityId before proceeding. However, it might be beneficial to add error handling for the setWakeWords call:

private async _wakeWordPicked(ev) {
  if (!this.assistEntityId) {
    return;
  }

  const wakeWordId = ev.currentTarget.value;

  try {
    await setWakeWords(this.hass, this.assistEntityId, [wakeWordId]);
    this._nextStep();
  } catch (error) {
    // Handle or log the error
    console.error("Failed to set wake word:", error);
    // Optionally, notify the user
  }
}

This change would make the component more robust by handling potential errors when setting the wake word.

this.hass,
"/voice_control/voice_remote_local_assistant/"
)}
rel="noreferrer noopenner"
Copy link
Contributor

Choose a reason for hiding this comment

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

Correct the typo in the rel attribute value.

At line 93, the rel attribute has a misspelling. The correct value should be noopener instead of noopenner.

Apply this diff to fix the typo:

-rel="noreferrer noopenner"
+rel="noreferrer noopener"
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rel="noreferrer noopenner"
rel="noreferrer noopener"

Comment on lines +116 to +130
for (const entity of Object.values(this.hass.entities)) {
if (entity.platform === "cloud") {
const domain = computeDomain(entity.entity_id);
if (domain === "tts") {
cloudTtsEntityId = entity.entity_id;
} else if (domain === "stt") {
cloudSttEntityId = entity.entity_id;
} else {
continue;
}
if (cloudTtsEntityId && cloudSttEntityId) {
break;
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix incorrect access to entity properties in _checkCloud() method.

In the _checkCloud() method, the code iterates over this.hass.entities and accesses entity.platform. However:

  • this.hass does not have an entities property; it should be this.hass.states.
  • The entity object retrieved from this.hass.states does not have a platform property.

To obtain the platform information, you may need to access entity.attributes.platform or adjust your approach based on how the platform data is stored.

Consider modifying the code as follows:

-for (const entity of Object.values(this.hass.entities)) {
+for (const entity of Object.values(this.hass.states)) {

And adjust the platform check:

-if (entity.platform === "cloud") {
+if (entity.attributes.platform === "cloud") {

Ensure that platform exists within entity.attributes. If not, you may need to revise your method for identifying cloud entities.

Committable suggestion was skipped due to low confidence.

Comment on lines +232 to +244
private _nextStep(ev) {
if (ev.detail?.updateConfig) {
this._fetchAssistConfiguration();
}
if (!ev.detail?.noPrevious) {
this._previousSteps.push(this._step);
}
if (ev.detail?.step) {
this._step = ev.detail.step;
} else {
this._step += 1;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Avoid incrementing enum values directly for step transitions

Incrementing the STEP enum using this._step += 1 may cause unexpected behavior if the enum values are changed or reordered in the future. It's safer to define explicit transitions between steps.

Consider modifying the code to use a mapping or a switch statement for step transitions. Here's an example using a switch statement:

private _nextStep(ev) {
  if (ev.detail?.updateConfig) {
    this._fetchAssistConfiguration();
  }
  if (!ev.detail?.noPrevious) {
    this._previousSteps.push(this._step);
  }
  if (ev.detail?.step) {
    this._step = ev.detail.step;
  } else {
    switch (this._step) {
      case STEP.UPDATE:
        this._step = STEP.CHECK;
        break;
      case STEP.CHECK:
        this._step = STEP.WAKEWORD;
        break;
      case STEP.WAKEWORD:
        this._step = STEP.AREA;
        break;
      // Add other cases as needed
      default:
        // Handle unexpected cases or set a default step
        break;
    }
  }
}

Comment on lines +28 to +39
export const enum STEP {
INIT,
UPDATE,
CHECK,
WAKEWORD,
AREA,
PIPELINE,
SUCCESS,
CLOUD,
ADDONS,
CHANGE_WAKEWORD,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Change 'const enum' to 'enum' to avoid compatibility issues

Using const enum is not supported by bundlers and is incompatible with TypeScript's --isolatedModules mode. This can lead to import issues and unexpected behavior.

Apply this diff to convert it to a regular enum:

-export const enum STEP {
+export enum STEP {
  INIT,
  UPDATE,
  CHECK,
  WAKEWORD,
  AREA,
  PIPELINE,
  SUCCESS,
  CLOUD,
  ADDONS,
  CHANGE_WAKEWORD,
}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const enum STEP {
INIT,
UPDATE,
CHECK,
WAKEWORD,
AREA,
PIPELINE,
SUCCESS,
CLOUD,
ADDONS,
CHANGE_WAKEWORD,
}
export enum STEP {
INIT,
UPDATE,
CHECK,
WAKEWORD,
AREA,
PIPELINE,
SUCCESS,
CLOUD,
ADDONS,
CHANGE_WAKEWORD,
}
Tools
Biome

[error] 28-39: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

Comment on lines +121 to +122
.label=${this.hass.localize("ui.dialogs.generic.close") ??
"Close"}
Copy link
Contributor

Choose a reason for hiding this comment

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

Update the label for the back navigation button

The label for the back button is currently set to "Close," which may be misleading to users. It should be updated to "Back" to accurately reflect its function.

Apply this diff to correct the label:

-  .label=${this.hass.localize("ui.dialogs.generic.close") ??
-  "Close"}
+  .label=${this.hass.localize("ui.dialogs.generic.back") ??
+  "Back"}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.label=${this.hass.localize("ui.dialogs.generic.close") ??
"Close"}
.label=${this.hass.localize("ui.dialogs.generic.back") ??
"Back"}

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 163ecd6 and 3dccc46.

Files selected for processing (3)
  • src/data/assist_satellite.ts (1 hunks)
  • src/dialogs/config-flow/step-flow-create-entry.ts (3 hunks)
  • src/panels/config/devices/ha-config-device-page.ts (4 hunks)
Files skipped from review as they are similar to previous changes (2)
  • src/dialogs/config-flow/step-flow-create-entry.ts
  • src/panels/config/devices/ha-config-device-page.ts
Additional context used
Biome
src/data/assist_satellite.ts

[error] 5-7: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

Additional comments not posted (7)
src/data/assist_satellite.ts (7)

1-3: LGTM: Imports are appropriate and concise.

The imports are relevant to the functionality being implemented in this file. Good job on keeping the imports minimal and focused.


9-25: LGTM: Well-structured interfaces with clear type definitions.

The interfaces WakeWordInterceptMessage, WakeWordOption, and AssistSatelliteConfiguration are well-defined and provide a clear structure for the assistant satellite system. The naming conventions are consistent and descriptive, and the types used are appropriate for their purposes.


27-35: LGTM: Well-implemented subscription function.

The interceptWakeWord function is well-implemented. It correctly uses the HomeAssistant's connection to subscribe to wake word interception messages. The function signature is clear, and the callback type matches the WakeWordInterceptMessage interface.


37-53: LGTM: Well-implemented API interaction functions.

Both testAssistSatelliteConnection and assistSatelliteAnnounce functions are well-implemented:

  1. testAssistSatelliteConnection correctly uses callWS for a WebSocket call to test the connection.
  2. assistSatelliteAnnounce appropriately uses callService to send an announcement.

The types and parameters are well-defined and suitable for their purposes.


55-73: LGTM: Well-implemented configuration management functions.

Both fetchAssistSatelliteConfiguration and setWakeWords functions are well-implemented:

  1. fetchAssistSatelliteConfiguration correctly specifies the return type as AssistSatelliteConfiguration and uses the appropriate WebSocket call.
  2. setWakeWords takes an array of wake word IDs as expected and makes the correct WebSocket call to update the configuration.

The types and parameters are well-defined and suitable for their purposes.


75-79: LGTM: Well-implemented support check function.

The assistSatelliteSupportsSetupFlow function is well-implemented:

  1. It correctly uses the supportsFeature utility to check for the ANNOUNCE feature.
  2. It handles the case where assistSatelliteEntity might be undefined.
  3. The function is concise and readable.

Good job on creating a clear and efficient support check.


1-79: Overall, well-implemented module for assist satellite functionality.

This new file introduces a comprehensive set of interfaces and functions for managing an assistive satellite system. The code is well-structured, with clear type definitions and appropriate use of Home Assistant's API. The only suggestion for improvement is to change the const enum to a regular enum for better compatibility.

Great job on implementing this new feature!

Tools
Biome

[error] 5-7: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 3dccc46 and 8714157.

Files selected for processing (2)
  • src/data/assist_satellite.ts (1 hunks)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-update.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/dialogs/voice-assistant-setup/voice-assistant-setup-step-update.ts
Additional context used
Biome
src/data/assist_satellite.ts

[error] 6-8: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

Additional comments not posted (6)
src/data/assist_satellite.ts (6)

10-12: LGTM: WakeWordInterceptMessage interface

The WakeWordInterceptMessage interface is well-defined and serves its purpose of representing wake word intercept messages.


14-18: LGTM: WakeWordOption interface

The WakeWordOption interface is well-structured, providing all necessary properties to represent a wake word option, including its identifier, the wake word itself, and the languages it has been trained in.


20-26: LGTM: AssistSatelliteConfiguration interface

The AssistSatelliteConfiguration interface is well-defined, providing a comprehensive structure for the assist satellite configuration. It includes all necessary properties such as active and available wake words, maximum active wake words, and relevant entity IDs.


28-36: LGTM: interceptWakeWord function

The interceptWakeWord function is well-implemented. It correctly uses the Home Assistant WebSocket connection to subscribe to wake word intercept messages for a specific entity. The function signature and implementation are appropriate for its purpose.


38-81: LGTM: Assist satellite interaction functions

The functions testAssistSatelliteConnection, assistSatelliteAnnounce, fetchAssistSatelliteConfiguration, setWakeWords, and assistSatelliteSupportsSetupFlow are well-implemented and serve their respective purposes effectively. They use appropriate Home Assistant API calls and follow consistent patterns for interacting with the assist satellite system.

The assistSatelliteSupportsSetupFlow function, in particular, includes proper checks for entity availability and feature support, which is a good practice for ensuring the reliability of the setup flow.


1-81: Excellent implementation of the assist satellite data layer

This file provides a comprehensive and well-structured foundation for interacting with the assist satellite system. It aligns perfectly with the PR objectives of introducing an MVP for the voice assist setup flow. The interfaces and functions cover all necessary aspects, including configuration management, wake word handling, and system interactions.

Key strengths of this implementation:

  1. Clear and concise interface definitions
  2. Consistent use of Home Assistant API calls
  3. Proper type annotations throughout the file
  4. Thoughtful function implementations that cover various use cases

The only minor issue (const enum usage) has been addressed in a previous comment. Once that's resolved, this file will serve as an excellent data layer for the voice assist feature.

Great job on laying the groundwork for this new feature!

Tools
Biome

[error] 6-8: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

Comment on lines +6 to +8
export const enum AssistSatelliteEntityFeature {
ANNOUNCE = 1,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Convert const enum to regular enum for better compatibility

The const keyword on the enum declaration can lead to compatibility issues with bundlers and the 'isolatedModules' mode in TypeScript, as pointed out by the static analysis tool.

To address this, please change the enum declaration to a regular enum:

export enum AssistSatelliteEntityFeature {
  ANNOUNCE = 1,
}

This change ensures better compatibility while maintaining the same functionality.

Tools
Biome

[error] 6-8: The enum declaration should not be const

Const enums are not supported by bundlers and are incompatible with the 'isolatedModules' mode. Their use can lead to import inexistent values.
See TypeScript Docs for more details.
Safe fix: Turn the const enum into a regular enum.

(lint/suspicious/noConstEnum)

piitaya
piitaya previously approved these changes Sep 24, 2024
Copy link
Member

@piitaya piitaya left a comment

Choose a reason for hiding this comment

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

I added some comments but it's not really blocking. We can improve that later 🙂

src/dialogs/config-flow/step-flow-create-entry.ts Outdated Show resolved Hide resolved
Comment on lines +13 to +19
@state() private _showFirst = false;

@state() private _showSecond = false;

@state() private _showThird = false;

@state() private _showFourth = false;
Copy link
Member

Choose a reason for hiding this comment

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

Can't we just used one counter for raspberry pi and one counter for home assistant cloud?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah but it gonna be removed anyway I think 🤷🏻‍♂️

Copy link
Contributor

@silamon silamon left a comment

Choose a reason for hiding this comment

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

There are some unfinished or uncorrect translations in this PR. I would polish a bit more.

@piitaya
Copy link
Member

piitaya commented Sep 24, 2024

@silamon This will not be available for users as no device implement this. It will be at first for internal tests using nightly build.

@bramkragten bramkragten merged commit 305cecb into dev Sep 24, 2024
13 checks passed
@bramkragten bramkragten deleted the voice-assist-flow branch September 24, 2024 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants