+ ${dynamicElement(
+ `matter-add-device-${this._step.replaceAll("_", "-")}`,
+ {
+ hass: this.hass,
+ }
+ )}
+
+ `;
+ }
+
+ private async _addDevice() {
+ const code = this._pairingCode;
+ const savedStep = this._step;
+ try {
+ this._step = "commissioning";
+ await commissionMatterDevice(this.hass, code);
+ } catch (err) {
+ showToast(this, {
+ message: this.hass.localize(
+ "ui.dialogs.matter-add-device.add_device_failed"
+ ),
+ duration: 2000,
+ });
+ }
+ this._step = savedStep;
+ }
+
+ private _renderActions() {
+ if (
+ this._step === "apple_home" ||
+ this._step === "google_home_fallback" ||
+ this._step === "generic"
+ ) {
+ return html`
+
+
+ -
+ ${this.hass.localize(
+ "ui.dialogs.matter-add-device.apple_home.step_1",
+ {
+ accessory_details: html`${this.hass.localize(
+ "ui.dialogs.matter-add-device.apple_home.accessory_details"
+ )}`,
+ }
+ )}
+
+ -
+ ${this.hass.localize(
+ "ui.dialogs.matter-add-device.apple_home.step_2",
+ {
+ turn_on_pairing_mode: html`${this.hass.localize(
+ "ui.dialogs.matter-add-device.apple_home.turn_on_pairing_mode"
+ )}`,
+ }
+ )}
+
+ -
+ ${this.hass.localize(
+ "ui.dialogs.matter-add-device.apple_home.step_3"
+ )}
+
+
+
+
+ ${this.hass.localize(
+ "ui.dialogs.matter-add-device.apple_home.code_instructions"
+ )}
+
+
+
+ `;
+ }
+
+ private _onCodeChanged(ev: any) {
+ const value = ev.currentTarget.value;
+ this._code = value;
+ fireEvent(this, "pairing-code-changed", { code: value });
+ }
+
+ static styles = [sharedStyles];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "matter-add-device-apple-home": MatterAddDeviceAppleHome;
+ }
+}
diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-commissioning.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-commissioning.ts
new file mode 100644
index 0000000000..b7825e1174
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-commissioning.ts
@@ -0,0 +1,47 @@
+import { LitElement, css, html } from "lit";
+import { customElement, property } from "lit/decorators";
+import { HomeAssistant } from "../../../../../../types";
+import { sharedStyles } from "./matter-add-device-shared-styles";
+import "../../../../../../components/ha-circular-progress";
+
+@customElement("matter-add-device-commissioning")
+class MatterAddDeviceCommissioning extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ render() {
+ return html`
+
+
+
+ ${this.hass.localize(
+ "ui.dialogs.matter-add-device.commissioning.note"
+ )}
+
+
+ `;
+ }
+
+ static styles = [
+ sharedStyles,
+ css`
+ .content {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ text-align: center;
+ }
+ ha-circular-progress {
+ margin-bottom: 24px;
+ }
+ `,
+ ];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "matter-add-device-commissioning": MatterAddDeviceCommissioning;
+ }
+}
diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-existing.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-existing.ts
new file mode 100644
index 0000000000..bbef0c0e94
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-existing.ts
@@ -0,0 +1,123 @@
+import { mdiHomeAutomation } from "@mdi/js";
+import { LitElement, css, html } from "lit";
+import { customElement, property } from "lit/decorators";
+import { fireEvent } from "../../../../../../common/dom/fire_event";
+import "../../../../../../components/ha-icon-next";
+import "../../../../../../components/ha-list-item-new";
+import "../../../../../../components/ha-list-new";
+import { HomeAssistant } from "../../../../../../types";
+import { MatterAddDeviceStep } from "../dialog-matter-add-device";
+import { sharedStyles } from "./matter-add-device-shared-styles";
+
+@customElement("matter-add-device-existing")
+class MatterAddDeviceExisting extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ render() {
+ return html`
+
+
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.existing.question`
+ )}
+
+
+
+
+
+ ${this.hass.localize(
+ "ui.dialogs.matter-add-device.generic.code_instructions"
+ )}
+
+
+
+ `;
+ }
+
+ private _onCodeChanged(ev: any) {
+ const value = ev.currentTarget.value;
+ this._code = value;
+ fireEvent(this, "pairing-code-changed", { code: value });
+ }
+
+ static styles = [sharedStyles];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "matter-add-device-generic": MatterAddDeviceGeneric;
+ }
+}
diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home-fallback.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home-fallback.ts
new file mode 100644
index 0000000000..4009f30da3
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home-fallback.ts
@@ -0,0 +1,85 @@
+import { LitElement, html } from "lit";
+import { customElement, property, state } from "lit/decorators";
+import { fireEvent } from "../../../../../../common/dom/fire_event";
+import "../../../../../../components/ha-icon-next";
+import "../../../../../../components/ha-list-item-new";
+import "../../../../../../components/ha-list-new";
+import { HomeAssistant } from "../../../../../../types";
+import { sharedStyles } from "./matter-add-device-shared-styles";
+
+@customElement("matter-add-device-google-home-fallback")
+class MatterAddDeviceGoogleHomeFallback extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @state() private _code: string = "";
+
+ render() {
+ return html`
+
+
+ -
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home_fallback.step_1`
+ )}
+
+ -
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home_fallback.step_2`,
+ {
+ linked_matter_apps_services: html`${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home_fallback.linked_matter_apps_services`
+ )}`,
+ }
+ )}
+
+ -
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home_fallback.step_3`,
+ {
+ link_apps_services: html`${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home_fallback.link_apps_services`
+ )}`,
+ use_pairing_code: html`${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home_fallback.use_pairing_code`
+ )}`,
+ }
+ )}
+
+
+
+
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home_fallback.code_instructions`
+ )}
+
+
+
+ `;
+ }
+
+ private _onCodeChanged(ev: any) {
+ const value = ev.currentTarget.value;
+ this._code = value;
+ fireEvent(this, "pairing-code-changed", { code: value });
+ }
+
+ static styles = [sharedStyles];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "matter-add-device-google-home-fallback": MatterAddDeviceGoogleHomeFallback;
+ }
+}
diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home.ts
new file mode 100644
index 0000000000..1c528cf524
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-google-home.ts
@@ -0,0 +1,82 @@
+import { LitElement, html } from "lit";
+import { customElement, property } from "lit/decorators";
+import { fireEvent } from "../../../../../../common/dom/fire_event";
+import "../../../../../../components/ha-icon-next";
+import "../../../../../../components/ha-list-item-new";
+import "../../../../../../components/ha-list-new";
+import { HomeAssistant } from "../../../../../../types";
+import { sharedStyles } from "./matter-add-device-shared-styles";
+
+@customElement("matter-add-device-google-home")
+class MatterAddDeviceGoogleHome extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ render() {
+ return html`
+
+
+ -
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home.step_1`
+ )}
+
+ -
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home.step_2`,
+ {
+ linked_matter_apps_services: html`${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home.linked_matter_apps_services`
+ )}`,
+ }
+ )}
+
+ -
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home.step_3`,
+ {
+ link_apps_services: html`${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home.link_apps_services`
+ )}`,
+ home_assistant: html`Home Assistant`,
+ }
+ )}
+
+
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home.no_home_assistant`
+ )}
+
+
+
+
+
+ ${this.hass.localize(
+ `ui.dialogs.matter-add-device.google_home.redirect`
+ )}
+
+
+ `;
+ }
+
+ private _nextStep() {
+ fireEvent(this, "step-selected", { step: "google_home_fallback" });
+ }
+
+ static styles = [sharedStyles];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "matter-add-device-google-home": MatterAddDeviceGoogleHome;
+ }
+}
diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-main.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-main.ts
new file mode 100644
index 0000000000..dc5b699034
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-main.ts
@@ -0,0 +1,80 @@
+import { LitElement, html } from "lit";
+import { customElement, property } from "lit/decorators";
+import { fireEvent } from "../../../../../../common/dom/fire_event";
+import "../../../../../../components/ha-icon-next";
+import "../../../../../../components/ha-list-item-new";
+import "../../../../../../components/ha-list-new";
+import { HomeAssistant } from "../../../../../../types";
+import { sharedStyles } from "./matter-add-device-shared-styles";
+
+@customElement("matter-add-device-main")
+class MatterAddDeviceMain extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ render() {
+ return html`
+
+
+ ${this.hass.localize(`ui.dialogs.matter-add-device.main.question`)}
+
+
+
+
${this.hass.localize("ui.dialogs.matter-add-device.new.note")}
+
+ ${this.hass.localize("ui.dialogs.matter-add-device.new.download_app")}
+
+
+
+ `;
+ }
+
+ static styles = [
+ sharedStyles,
+ css`
+ .app-qr {
+ margin: 24px auto 0 auto;
+ display: flex;
+ justify-content: space-between;
+ padding: 0 24px;
+ box-sizing: border-box;
+ gap: 16px;
+ width: 100%;
+ max-width: 400px;
+ }
+ .app-qr a,
+ .app-qr img {
+ flex: 1;
+ }
+ `,
+ ];
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "matter-add-device-new": MatterAddDeviceNew;
+ }
+}
diff --git a/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-shared-styles.ts b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-shared-styles.ts
new file mode 100644
index 0000000000..ca36a5f36b
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/matter/matter-add-device/matter-add-device-shared-styles.ts
@@ -0,0 +1,35 @@
+import { css } from "lit";
+
+export const sharedStyles = css`
+ .content {
+ padding: 16px var(--horizontal-padding, 16px);
+ }
+ p {
+ margin: 0;
+ }
+ p:not(:last-child) {
+ margin-bottom: 8px;
+ }
+ ol {
+ padding-inline-start: 20px;
+ margin-block-start: 0;
+ margin-block-end: 8px;
+ }
+ li {
+ margin-bottom: 8px;
+ }
+ .link {
+ color: var(--primary-color);
+ cursor: pointer;
+ text-decoration: underline;
+ }
+ ha-list-new {
+ padding: 0;
+ --md-list-item-leading-space: var(--horizontal-padding, 16px);
+ --md-list-item-trailing-space: var(--horizontal-padding, 16px);
+ margin-bottom: 16px;
+ }
+ ha-textfield {
+ width: 100%;
+ }
+`;
diff --git a/src/translations/en.json b/src/translations/en.json
index 68edd0d0f3..cd82c08792 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -1657,6 +1657,72 @@
"title": "Create backup?",
"text": "This will create a backup before installing.",
"create": "Create"
+ },
+ "matter-add-device": {
+ "add_device": "Add device",
+ "add_device_failed": "Failed to add the device",
+ "commissioning": {
+ "header": "Add Matter device",
+ "note": "Adding the device, this may take a minute or two."
+ },
+ "main": {
+ "header": "Add Matter device",
+ "question": "Is your device already added to another Matter controller?",
+ "answer_new": "No. It’s new.",
+ "answer_new_description": "My device is brand new or factory reset.",
+ "answer_existing": "Yes. It’s already in use.",
+ "answer_existing_description": "My device is connected to another controller."
+ },
+ "new": {
+ "header": "[%key:ui::dialogs::matter-add-device::main::header%]",
+ "note": "You need to use the Home Assistant Companion app on your mobile phone to add Matter devices.",
+ "download_app": "Install it from the Google Play Store or the App Store if you don't have it.",
+ "playstore": "[%key:ui::panel::page-onboarding::welcome::playstore%]",
+ "appstore": "[%key:ui::panel::page-onboarding::welcome::appstore%]"
+ },
+ "existing": {
+ "header": "[%key:ui::dialogs::matter-add-device::main::header%]",
+ "question": "Which controller is it connected to?",
+ "answer_google_home": "Google Home",
+ "answer_apple_home": "Apple Home",
+ "answer_generic": "Other controllers"
+ },
+ "google_home": {
+ "header": "Link Matter app",
+ "step_1": "Find your device in Google Home. Tap the gear icon to open the device settings.",
+ "step_2": "Tap {linked_matter_apps_services}.",
+ "step_3": "Tap {link_apps_services} and choose {home_assistant} from the list.",
+ "linked_matter_apps_services": "Linked Matter apps & services",
+ "link_apps_services": "Link apps & services",
+ "no_home_assistant": "I can’t find Home Assistant on the list",
+ "redirect": "You are redirected to the Home Assistant app. Please follow the instructions."
+ },
+ "google_home_fallback": {
+ "header": "Copy pairing code",
+ "step_1": "[%key:ui::dialogs::matter-add-device::google_home::step_1%]",
+ "step_2": "[%key:ui::dialogs::matter-add-device::google_home::step_2%]",
+ "step_3": "Tap {link_apps_services} and choose {use_pairing_code} form the list",
+ "linked_matter_apps_services": "[%key:ui::dialogs::matter-add-device::google_home::linked_matter_apps_services%]",
+ "link_apps_services": "[%key:ui::dialogs::matter-add-device::google_home::link_apps_services%]",
+ "use_pairing_code": "Use Pairing Code",
+ "pairing_code": "Pairing code",
+ "code_instructions": "Paste the code you just received from the other controller."
+ },
+ "apple_home": {
+ "header": "Copy setup code",
+ "step_1": "Find your device in Apple Home and open {accessory_details}.",
+ "step_2": "Scroll all the way down and tap {turn_on_pairing_mode}.",
+ "step_3": "You now see the setup code.",
+ "accessory_details": "Accessory Details",
+ "turn_on_pairing_mode": "Turn On Pairing Mode",
+ "setup_code": "Setup code",
+ "code_instructions": "Paste the code you just received from the other controller."
+ },
+ "generic": {
+ "header": "Copy setup code",
+ "code_instructions": "Search for the sharing mode in the app of your controller, and activate it. You will get a sharing code, enter that below.",
+ "setup_code": "Setup code"
+ }
}
},
"weekdays": {
@@ -4182,7 +4248,6 @@
"missing_zwave_zigbee_title": "{integration} is not setup",
"missing_zwave_zigbee": "To add a {brand} device, you first need {supported_hardware_link} and the {integration} integration set up. If you already have the hardware then you can proceed with the setup of {integration}.",
"missing_matter": "To add a {brand} device, you first need the {integration} integration and {supported_hardware_link}. Do you want to proceed with the setup of {integration}?",
- "matter_mobile_app": "You need to use the Home Assistant Companion app on your mobile phone to commission Matter devices.",
"supported_hardware": "supported hardware",
"proceed": "Proceed",
"single_config_entry_title": "This integration allows only one configuration",
@@ -6623,7 +6688,9 @@
"forums": "Home Assistant forums",
"open_home_newsletter": "Building the Open Home newsletter",
"discord": "Discord chat",
- "twitter": "Twitter"
+ "twitter": "Twitter",
+ "playstore": "Get it on Google Play",
+ "appstore": "Download on the App Store"
},
"user": {
"header": "Create user",