mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add matter device info and actions (#19578)
* add matter device info panel (WIP) * actually enable card on device page * fix remove fabric * add some translation labels * add dialog to interview node * do not show info for bridged devices * first device action * add ping node action and dialog * ping should be always available * update model for MatterCommissioningParameters * add basic support for open commissioning window * move fabric management to dialog * review * Add link to thread panel --------- Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
b700e08d52
commit
b159f4c074
@ -3,6 +3,50 @@ import { navigate } from "../common/navigate";
|
|||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import { subscribeDeviceRegistry } from "./device_registry";
|
import { subscribeDeviceRegistry } from "./device_registry";
|
||||||
|
|
||||||
|
export enum NetworkType {
|
||||||
|
THREAD = "thread",
|
||||||
|
WIFI = "wifi",
|
||||||
|
ETHERNET = "ethernet",
|
||||||
|
UNKNOWN = "unknown",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum NodeType {
|
||||||
|
END_DEVICE = "end_device",
|
||||||
|
SLEEPY_END_DEVICE = "sleepy_end_device",
|
||||||
|
ROUTING_END_DEVICE = "routing_end_device",
|
||||||
|
BRIDGE = "bridge",
|
||||||
|
UNKNOWN = "unknown",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MatterFabricData {
|
||||||
|
fabric_id: number;
|
||||||
|
vendor_id: number;
|
||||||
|
fabric_index: number;
|
||||||
|
fabric_label?: string;
|
||||||
|
vendor_name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MatterNodeDiagnostics {
|
||||||
|
node_id: number;
|
||||||
|
network_type: NetworkType;
|
||||||
|
node_type: NodeType;
|
||||||
|
network_name?: string;
|
||||||
|
ip_adresses: string[];
|
||||||
|
mac_address?: string;
|
||||||
|
available: boolean;
|
||||||
|
active_fabrics: MatterFabricData[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MatterPingResult {
|
||||||
|
[ip_address: string]: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MatterCommissioningParameters {
|
||||||
|
setup_pin_code: number;
|
||||||
|
setup_manual_code: string;
|
||||||
|
setup_qr_code: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const canCommissionMatterExternal = (hass: HomeAssistant) =>
|
export const canCommissionMatterExternal = (hass: HomeAssistant) =>
|
||||||
hass.auth.external?.config.canCommissionMatter;
|
hass.auth.external?.config.canCommissionMatter;
|
||||||
|
|
||||||
@ -86,3 +130,50 @@ export const matterSetThread = (
|
|||||||
type: "matter/set_thread",
|
type: "matter/set_thread",
|
||||||
thread_operation_dataset,
|
thread_operation_dataset,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const getMatterNodeDiagnostics = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device_id: string
|
||||||
|
): Promise<MatterNodeDiagnostics> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "matter/node_diagnostics",
|
||||||
|
device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const pingMatterNode = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device_id: string
|
||||||
|
): Promise<MatterPingResult> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "matter/ping_node",
|
||||||
|
device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const openMatterCommissioningWindow = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device_id: string
|
||||||
|
): Promise<MatterCommissioningParameters> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "matter/open_commissioning_window",
|
||||||
|
device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const removeMatterFabric = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device_id: string,
|
||||||
|
fabric_index: number
|
||||||
|
): Promise<void> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "matter/remove_matter_fabric",
|
||||||
|
device_id,
|
||||||
|
fabric_index,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const interviewMatterNode = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device_id: string
|
||||||
|
): Promise<void> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "matter/interview_node",
|
||||||
|
device_id,
|
||||||
|
});
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
import {
|
||||||
|
mdiAccessPoint,
|
||||||
|
mdiChatProcessing,
|
||||||
|
mdiChatQuestion,
|
||||||
|
mdiExportVariant,
|
||||||
|
} from "@mdi/js";
|
||||||
|
import { DeviceRegistryEntry } from "../../../../../../data/device_registry";
|
||||||
|
import {
|
||||||
|
NetworkType,
|
||||||
|
getMatterNodeDiagnostics,
|
||||||
|
} from "../../../../../../data/matter";
|
||||||
|
import type { HomeAssistant } from "../../../../../../types";
|
||||||
|
import { showMatterReinterviewNodeDialog } from "../../../../integrations/integration-panels/matter/show-dialog-matter-reinterview-node";
|
||||||
|
import { showMatterPingNodeDialog } from "../../../../integrations/integration-panels/matter/show-dialog-matter-ping-node";
|
||||||
|
import { showMatterOpenCommissioningWindowDialog } from "../../../../integrations/integration-panels/matter/show-dialog-matter-open-commissioning-window";
|
||||||
|
import type { DeviceAction } from "../../../ha-config-device-page";
|
||||||
|
import { showMatterManageFabricsDialog } from "../../../../integrations/integration-panels/matter/show-dialog-matter-manage-fabrics";
|
||||||
|
import { navigate } from "../../../../../../common/navigate";
|
||||||
|
|
||||||
|
export const getMatterDeviceActions = async (
|
||||||
|
el: HTMLElement,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
device: DeviceRegistryEntry
|
||||||
|
): Promise<DeviceAction[]> => {
|
||||||
|
if (device.via_device_id !== null) {
|
||||||
|
// only show device actions for top level nodes (so not bridged)
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeDiagnostics = await getMatterNodeDiagnostics(hass, device.id);
|
||||||
|
|
||||||
|
const actions: DeviceAction[] = [];
|
||||||
|
|
||||||
|
if (nodeDiagnostics.available) {
|
||||||
|
// actions that can only be performed if the device is alive
|
||||||
|
actions.push({
|
||||||
|
label: hass.localize(
|
||||||
|
"ui.panel.config.matter.device_actions.open_commissioning_window"
|
||||||
|
),
|
||||||
|
icon: mdiExportVariant,
|
||||||
|
action: () =>
|
||||||
|
showMatterOpenCommissioningWindowDialog(el, {
|
||||||
|
device_id: device.id,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
label: hass.localize(
|
||||||
|
"ui.panel.config.matter.device_actions.manage_fabrics"
|
||||||
|
),
|
||||||
|
icon: mdiExportVariant,
|
||||||
|
action: () =>
|
||||||
|
showMatterManageFabricsDialog(el, {
|
||||||
|
device_id: device.id,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
label: hass.localize(
|
||||||
|
"ui.panel.config.matter.device_actions.reinterview_device"
|
||||||
|
),
|
||||||
|
icon: mdiChatProcessing,
|
||||||
|
action: () =>
|
||||||
|
showMatterReinterviewNodeDialog(el, {
|
||||||
|
device_id: device.id,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeDiagnostics.network_type === NetworkType.THREAD) {
|
||||||
|
actions.push({
|
||||||
|
label: hass.localize(
|
||||||
|
"ui.panel.config.matter.device_actions.view_thread_network"
|
||||||
|
),
|
||||||
|
icon: mdiAccessPoint,
|
||||||
|
action: () => navigate("/config/thread"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.push({
|
||||||
|
label: hass.localize("ui.panel.config.matter.device_actions.ping_device"),
|
||||||
|
icon: mdiChatQuestion,
|
||||||
|
action: () =>
|
||||||
|
showMatterPingNodeDialog(el, {
|
||||||
|
device_id: device.id,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
};
|
@ -0,0 +1,174 @@
|
|||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import "../../../../../../components/ha-expansion-panel";
|
||||||
|
import { DeviceRegistryEntry } from "../../../../../../data/device_registry";
|
||||||
|
import {
|
||||||
|
getMatterNodeDiagnostics,
|
||||||
|
MatterNodeDiagnostics,
|
||||||
|
} from "../../../../../../data/matter";
|
||||||
|
import "@material/mwc-list";
|
||||||
|
import "../../../../../../components/ha-list-item";
|
||||||
|
import { SubscribeMixin } from "../../../../../../mixins/subscribe-mixin";
|
||||||
|
import { haStyle } from "../../../../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../../../../types";
|
||||||
|
|
||||||
|
@customElement("ha-device-info-matter")
|
||||||
|
export class HaDeviceInfoMatter extends SubscribeMixin(LitElement) {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public device!: DeviceRegistryEntry;
|
||||||
|
|
||||||
|
@state() private _nodeDiagnostics?: MatterNodeDiagnostics;
|
||||||
|
|
||||||
|
public willUpdate(changedProperties: PropertyValues) {
|
||||||
|
super.willUpdate(changedProperties);
|
||||||
|
if (changedProperties.has("device")) {
|
||||||
|
this._fetchNodeDetails();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchNodeDetails() {
|
||||||
|
if (!this.device) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.device.via_device_id !== null) {
|
||||||
|
// only show device details for top level nodes (so not bridged)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._nodeDiagnostics = await getMatterNodeDiagnostics(
|
||||||
|
this.hass,
|
||||||
|
this.device.id
|
||||||
|
);
|
||||||
|
} catch (err: any) {
|
||||||
|
this._nodeDiagnostics = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._nodeDiagnostics) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<ha-expansion-panel
|
||||||
|
.header=${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.device_info.device_info"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div class="row">
|
||||||
|
<span class="name"
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.device_info.node_id"
|
||||||
|
)}:</span
|
||||||
|
>
|
||||||
|
<span class="value">${this._nodeDiagnostics.node_id}</span>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span class="name"
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.device_info.network_type"
|
||||||
|
)}:</span
|
||||||
|
>
|
||||||
|
<span class="value"
|
||||||
|
>${this.hass.localize(
|
||||||
|
`ui.panel.config.matter.network_type.${this._nodeDiagnostics.network_type}`
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span class="name"
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.device_info.node_type"
|
||||||
|
)}:</span
|
||||||
|
>
|
||||||
|
<span class="value"
|
||||||
|
>${this.hass.localize(
|
||||||
|
`ui.panel.config.matter.node_type.${this._nodeDiagnostics.node_type}`
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
${this._nodeDiagnostics.network_name
|
||||||
|
? html`
|
||||||
|
<div class="row">
|
||||||
|
<span class="name"
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.device_info.network_name"
|
||||||
|
)}:</span
|
||||||
|
>
|
||||||
|
<span class="value">${this._nodeDiagnostics.network_name}</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
${this._nodeDiagnostics.mac_address
|
||||||
|
? html`
|
||||||
|
<div class="row">
|
||||||
|
<span class="name"
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.device_info.mac_address"
|
||||||
|
)}:</span
|
||||||
|
>
|
||||||
|
<span class="value">${this._nodeDiagnostics.mac_address}</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<span class="name"
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.device_info.ip_adresses"
|
||||||
|
)}:</span
|
||||||
|
>
|
||||||
|
<span class="value"
|
||||||
|
>${this._nodeDiagnostics.ip_adresses.map(
|
||||||
|
(ip) => html`${ip}<br />`
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</ha-expansion-panel>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
h4 {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
word-break: break-all;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
ha-expansion-panel {
|
||||||
|
margin: 8px -16px 0;
|
||||||
|
--expansion-panel-summary-padding: 0 16px;
|
||||||
|
--expansion-panel-content-padding: 0 16px;
|
||||||
|
--ha-card-border-radius: 0px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-device-info-matter": HaDeviceInfoMatter;
|
||||||
|
}
|
||||||
|
}
|
@ -1099,6 +1099,17 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
);
|
);
|
||||||
deviceActions.push(...actions);
|
deviceActions.push(...actions);
|
||||||
}
|
}
|
||||||
|
if (domains.includes("matter")) {
|
||||||
|
const matter = await import(
|
||||||
|
"./device-detail/integration-elements/matter/device-actions"
|
||||||
|
);
|
||||||
|
const actions = await matter.getMatterDeviceActions(
|
||||||
|
this,
|
||||||
|
this.hass,
|
||||||
|
device
|
||||||
|
);
|
||||||
|
deviceActions.push(...actions);
|
||||||
|
}
|
||||||
|
|
||||||
this._deviceActions = deviceActions;
|
this._deviceActions = deviceActions;
|
||||||
}
|
}
|
||||||
@ -1204,6 +1215,17 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
></ha-device-info-zwave_js>
|
></ha-device-info-zwave_js>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
if (domains.includes("matter")) {
|
||||||
|
import(
|
||||||
|
"./device-detail/integration-elements/matter/ha-device-info-matter"
|
||||||
|
);
|
||||||
|
deviceInfo.push(html`
|
||||||
|
<ha-device-info-matter
|
||||||
|
.hass=${this.hass}
|
||||||
|
.device=${device}
|
||||||
|
></ha-device-info-matter>
|
||||||
|
`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _showSettings() {
|
private async _showSettings() {
|
||||||
|
@ -0,0 +1,169 @@
|
|||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import { mdiClose } from "@mdi/js";
|
||||||
|
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../../../../../components/ha-circular-progress";
|
||||||
|
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||||
|
import "../../../../../components/ha-qr-code";
|
||||||
|
import {
|
||||||
|
MatterFabricData,
|
||||||
|
MatterNodeDiagnostics,
|
||||||
|
getMatterNodeDiagnostics,
|
||||||
|
removeMatterFabric,
|
||||||
|
} from "../../../../../data/matter";
|
||||||
|
import {
|
||||||
|
showAlertDialog,
|
||||||
|
showConfirmationDialog,
|
||||||
|
} from "../../../../../dialogs/generic/show-dialog-box";
|
||||||
|
import { haStyleDialog } from "../../../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { MatterManageFabricsDialogParams } from "./show-dialog-matter-manage-fabrics";
|
||||||
|
|
||||||
|
const NABUCASA_FABRIC = 4939;
|
||||||
|
|
||||||
|
@customElement("dialog-matter-manage-fabrics")
|
||||||
|
class DialogMatterManageFabrics extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private device_id?: string;
|
||||||
|
|
||||||
|
@state() private _nodeDiagnostics?: MatterNodeDiagnostics;
|
||||||
|
|
||||||
|
public async showDialog(
|
||||||
|
params: MatterManageFabricsDialogParams
|
||||||
|
): Promise<void> {
|
||||||
|
this.device_id = params.device_id;
|
||||||
|
this._fetchNodeDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.device_id) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-dialog
|
||||||
|
open
|
||||||
|
hideActions
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
.heading=${createCloseHeading(
|
||||||
|
this.hass,
|
||||||
|
this.hass.localize("ui.panel.config.matter.manage_fabrics.title")
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize("ui.panel.config.matter.manage_fabrics.fabrics")}
|
||||||
|
</p>
|
||||||
|
${this._nodeDiagnostics
|
||||||
|
? html`<mwc-list>
|
||||||
|
${this._nodeDiagnostics.active_fabrics.map(
|
||||||
|
(fabric) =>
|
||||||
|
html`<ha-list-item
|
||||||
|
noninteractive
|
||||||
|
.hasMeta=${this._nodeDiagnostics?.available &&
|
||||||
|
fabric.vendor_id !== NABUCASA_FABRIC}
|
||||||
|
>${fabric.vendor_name ||
|
||||||
|
fabric.fabric_label ||
|
||||||
|
fabric.vendor_id}
|
||||||
|
<ha-icon-button
|
||||||
|
@click=${this._removeFabric}
|
||||||
|
slot="meta"
|
||||||
|
.fabric=${fabric}
|
||||||
|
.path=${mdiClose}
|
||||||
|
></ha-icon-button>
|
||||||
|
</ha-list-item>`
|
||||||
|
)}
|
||||||
|
</mwc-list>`
|
||||||
|
: html`<div class="center">
|
||||||
|
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||||
|
</div>`}
|
||||||
|
</ha-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchNodeDetails() {
|
||||||
|
if (!this.device_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._nodeDiagnostics = await getMatterNodeDiagnostics(
|
||||||
|
this.hass,
|
||||||
|
this.device_id
|
||||||
|
);
|
||||||
|
} catch (err: any) {
|
||||||
|
this._nodeDiagnostics = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _removeFabric(ev) {
|
||||||
|
const fabric: MatterFabricData = ev.target.fabric;
|
||||||
|
const fabricName =
|
||||||
|
fabric.vendor_name || fabric.fabric_label || fabric.vendor_id.toString();
|
||||||
|
const confirm = await showConfirmationDialog(this, {
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.panel.config.matter.manage_fabrics.remove_fabric_confirm_header",
|
||||||
|
{ fabric: fabricName }
|
||||||
|
),
|
||||||
|
text: this.hass.localize(
|
||||||
|
"ui.panel.config.matter.manage_fabrics.remove_fabric_confirm_text",
|
||||||
|
{ fabric: fabricName }
|
||||||
|
),
|
||||||
|
warning: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirm) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await removeMatterFabric(this.hass, this.device_id!, fabric.fabric_index);
|
||||||
|
this._fetchNodeDetails();
|
||||||
|
} catch (err: any) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.panel.config.matter.manage_fabrics.remove_fabric_failed_header",
|
||||||
|
{ fabric: fabricName }
|
||||||
|
),
|
||||||
|
text: this.hass.localize(
|
||||||
|
"ui.panel.config.matter.manage_fabrics.remove_fabric_failed_text"
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this.device_id = undefined;
|
||||||
|
this._nodeDiagnostics = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
ha-dialog {
|
||||||
|
--dialog-content-padding: 0;
|
||||||
|
--mdc-list-side-padding: 24px;
|
||||||
|
--mdc-list-side-padding-right: 16px;
|
||||||
|
--mdc-list-item-meta-size: 48px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 8px 24px;
|
||||||
|
}
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-matter-manage-fabrics": DialogMatterManageFabrics;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,200 @@
|
|||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import { mdiCheckCircle, mdiCloseCircle } from "@mdi/js";
|
||||||
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../../../../../components/ha-circular-progress";
|
||||||
|
import "../../../../../components/ha-qr-code";
|
||||||
|
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||||
|
import {
|
||||||
|
openMatterCommissioningWindow,
|
||||||
|
MatterCommissioningParameters,
|
||||||
|
} from "../../../../../data/matter";
|
||||||
|
import { haStyleDialog } from "../../../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { MatterOpenCommissioningWindowDialogParams } from "./show-dialog-matter-open-commissioning-window";
|
||||||
|
|
||||||
|
@customElement("dialog-matter-open-commissioning-window")
|
||||||
|
class DialogMatterOpenCommissioningWindow extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private device_id?: string;
|
||||||
|
|
||||||
|
@state() private _status?: string;
|
||||||
|
|
||||||
|
@state() private _commissionParams?: MatterCommissioningParameters;
|
||||||
|
|
||||||
|
public async showDialog(
|
||||||
|
params: MatterOpenCommissioningWindowDialogParams
|
||||||
|
): Promise<void> {
|
||||||
|
this.device_id = params.device_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.device_id) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-dialog
|
||||||
|
open
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
.heading=${createCloseHeading(
|
||||||
|
this.hass,
|
||||||
|
this.hass.localize(
|
||||||
|
"ui.panel.config.matter.open_commissioning_window.title"
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
${this._commissionParams
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCheckCircle}
|
||||||
|
class="success"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.open_commissioning_window.sharing_code"
|
||||||
|
)}: <b>${this._commissionParams.setup_manual_code}</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ha-qr-code
|
||||||
|
.data=${this._commissionParams.setup_qr_code}
|
||||||
|
errorCorrectionLevel="quartile"
|
||||||
|
scale="6"
|
||||||
|
></ha-qr-code>
|
||||||
|
<div></div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "started"
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
<b>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.open_commissioning_window.in_progress"
|
||||||
|
)}
|
||||||
|
</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "failed"
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCloseCircle}
|
||||||
|
class="failed"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.open_commissioning_window.failed"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.open_commissioning_window.introduction"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this._start}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.open_commissioning_window.start_commissioning"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
`}
|
||||||
|
</ha-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _start(): Promise<void> {
|
||||||
|
if (!this.hass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._status = "started";
|
||||||
|
this._commissionParams = undefined;
|
||||||
|
try {
|
||||||
|
this._commissionParams = await openMatterCommissioningWindow(
|
||||||
|
this.hass,
|
||||||
|
this.device_id!
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
this._status = "failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this.device_id = undefined;
|
||||||
|
this._status = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
.success {
|
||||||
|
color: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.failed {
|
||||||
|
color: var(--error-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stages {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage ha-svg-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
.stage {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-svg-icon {
|
||||||
|
width: 68px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-qr-code {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container ha-circular-progress,
|
||||||
|
.flex-container ha-svg-icon {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-matter-open-commissioning-window": DialogMatterOpenCommissioningWindow;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,199 @@
|
|||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import { mdiCheckCircle, mdiCloseCircle } from "@mdi/js";
|
||||||
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../../../../../components/ha-circular-progress";
|
||||||
|
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||||
|
import { pingMatterNode, MatterPingResult } from "../../../../../data/matter";
|
||||||
|
import { haStyleDialog } from "../../../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { MatterPingNodeDialogParams } from "./show-dialog-matter-ping-node";
|
||||||
|
|
||||||
|
@customElement("dialog-matter-ping-node")
|
||||||
|
class DialogMatterPingNode extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private device_id?: string;
|
||||||
|
|
||||||
|
@state() private _status?: string;
|
||||||
|
|
||||||
|
@state() private _pingResult?: MatterPingResult;
|
||||||
|
|
||||||
|
public async showDialog(params: MatterPingNodeDialogParams): Promise<void> {
|
||||||
|
this.device_id = params.device_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.device_id) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-dialog
|
||||||
|
open
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
.heading=${createCloseHeading(
|
||||||
|
this.hass,
|
||||||
|
this.hass.localize("ui.panel.config.matter.ping_node.title")
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
${this._pingResult
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCheckCircle}
|
||||||
|
class="success"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.ping_node.ping_complete"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<mwc-list>
|
||||||
|
${Object.entries(this._pingResult).map(
|
||||||
|
([ip, success]) =>
|
||||||
|
html`<ha-list-item hasMeta
|
||||||
|
>${ip}
|
||||||
|
<ha-icon
|
||||||
|
slot="meta"
|
||||||
|
icon=${success ? "mdi:check" : "mdi:close"}
|
||||||
|
></ha-icon>
|
||||||
|
</ha-list-item>`
|
||||||
|
)}
|
||||||
|
</mwc-list>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "started"
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
<b>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.ping_node.in_progress"
|
||||||
|
)}
|
||||||
|
</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "failed"
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCloseCircle}
|
||||||
|
class="failed"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.ping_node.ping_failed"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.ping_node.introduction"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<em>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.ping_node.battery_device_warning"
|
||||||
|
)}
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this._startPing}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.ping_node.start_ping"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
`}
|
||||||
|
</ha-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _startPing(): Promise<void> {
|
||||||
|
if (!this.hass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._status = "started";
|
||||||
|
try {
|
||||||
|
this._pingResult = await pingMatterNode(this.hass, this.device_id!);
|
||||||
|
} catch (err) {
|
||||||
|
this._status = "failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this.device_id = undefined;
|
||||||
|
this._status = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
.success {
|
||||||
|
color: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.failed {
|
||||||
|
color: var(--error-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stages {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage ha-svg-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
.stage {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-svg-icon {
|
||||||
|
width: 68px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container ha-circular-progress,
|
||||||
|
.flex-container ha-svg-icon {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-matter-ping-node": DialogMatterPingNode;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,193 @@
|
|||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import { mdiCheckCircle, mdiCloseCircle } from "@mdi/js";
|
||||||
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../../../../../components/ha-circular-progress";
|
||||||
|
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||||
|
import { interviewMatterNode } from "../../../../../data/matter";
|
||||||
|
import { haStyleDialog } from "../../../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { MatterReinterviewNodeDialogParams } from "./show-dialog-matter-reinterview-node";
|
||||||
|
|
||||||
|
@customElement("dialog-matter-reinterview-node")
|
||||||
|
class DialogMatterReinterviewNode extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private device_id?: string;
|
||||||
|
|
||||||
|
@state() private _status?: string;
|
||||||
|
|
||||||
|
public async showDialog(
|
||||||
|
params: MatterReinterviewNodeDialogParams
|
||||||
|
): Promise<void> {
|
||||||
|
this.device_id = params.device_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.device_id) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-dialog
|
||||||
|
open
|
||||||
|
@closed=${this.closeDialog}
|
||||||
|
.heading=${createCloseHeading(
|
||||||
|
this.hass,
|
||||||
|
this.hass.localize("ui.panel.config.matter.reinterview_node.title")
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
${!this._status
|
||||||
|
? html`
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.reinterview_node.introduction"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<em>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.reinterview_node.battery_device_warning"
|
||||||
|
)}
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this._startReinterview}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.reinterview_node.start_reinterview"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "started"
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
<b>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.reinterview_node.in_progress"
|
||||||
|
)}
|
||||||
|
</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.reinterview_node.run_in_background"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "failed"
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCloseCircle}
|
||||||
|
class="failed"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.reinterview_node.interview_failed"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "finished"
|
||||||
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCheckCircle}
|
||||||
|
class="success"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.matter.reinterview_node.interview_complete"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
</ha-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _startReinterview(): Promise<void> {
|
||||||
|
if (!this.hass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._status = "started";
|
||||||
|
try {
|
||||||
|
await interviewMatterNode(this.hass, this.device_id!);
|
||||||
|
this._status = "finished";
|
||||||
|
} catch (err) {
|
||||||
|
this._status = "failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this.device_id = undefined;
|
||||||
|
this._status = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResultGroup {
|
||||||
|
return [
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
|
.success {
|
||||||
|
color: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.failed {
|
||||||
|
color: var(--error-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stages {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage ha-svg-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
.stage {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-svg-icon {
|
||||||
|
width: 68px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container ha-circular-progress,
|
||||||
|
.flex-container ha-svg-icon {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-matter-reinterview-node": DialogMatterReinterviewNode;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
|
||||||
|
export interface MatterManageFabricsDialogParams {
|
||||||
|
device_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadManageFabricsDialog = () =>
|
||||||
|
import("./dialog-matter-manage-fabrics");
|
||||||
|
|
||||||
|
export const showMatterManageFabricsDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
dialogParams: MatterManageFabricsDialogParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-matter-manage-fabrics",
|
||||||
|
dialogImport: loadManageFabricsDialog,
|
||||||
|
dialogParams,
|
||||||
|
});
|
||||||
|
};
|
@ -0,0 +1,19 @@
|
|||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
|
||||||
|
export interface MatterOpenCommissioningWindowDialogParams {
|
||||||
|
device_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadOpenCommissioningWindowDialog = () =>
|
||||||
|
import("./dialog-matter-open-commissioning-window");
|
||||||
|
|
||||||
|
export const showMatterOpenCommissioningWindowDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
dialogParams: MatterOpenCommissioningWindowDialogParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-matter-open-commissioning-window",
|
||||||
|
dialogImport: loadOpenCommissioningWindowDialog,
|
||||||
|
dialogParams,
|
||||||
|
});
|
||||||
|
};
|
@ -0,0 +1,18 @@
|
|||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
|
||||||
|
export interface MatterPingNodeDialogParams {
|
||||||
|
device_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadPingNodeDialog = () => import("./dialog-matter-ping-node");
|
||||||
|
|
||||||
|
export const showMatterPingNodeDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
pingNodeDialogParams: MatterPingNodeDialogParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-matter-ping-node",
|
||||||
|
dialogImport: loadPingNodeDialog,
|
||||||
|
dialogParams: pingNodeDialogParams,
|
||||||
|
});
|
||||||
|
};
|
@ -0,0 +1,19 @@
|
|||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
|
||||||
|
export interface MatterReinterviewNodeDialogParams {
|
||||||
|
device_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadReinterviewNodeDialog = () =>
|
||||||
|
import("./dialog-matter-reinterview-node");
|
||||||
|
|
||||||
|
export const showMatterReinterviewNodeDialog = (
|
||||||
|
element: HTMLElement,
|
||||||
|
reinterviewNodeDialogParams: MatterReinterviewNodeDialogParams
|
||||||
|
): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-matter-reinterview-node",
|
||||||
|
dialogImport: loadReinterviewNodeDialog,
|
||||||
|
dialogParams: reinterviewNodeDialogParams,
|
||||||
|
});
|
||||||
|
};
|
@ -4597,6 +4597,73 @@
|
|||||||
"download_logs": "Download logs"
|
"download_logs": "Download logs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"matter": {
|
||||||
|
"network_type": {
|
||||||
|
"thread": "Thread",
|
||||||
|
"wifi": "Wi-Fi",
|
||||||
|
"ethernet": "Ethernet",
|
||||||
|
"unknown": "Unknown"
|
||||||
|
},
|
||||||
|
"node_type": {
|
||||||
|
"end_device": "End-device",
|
||||||
|
"sleepy_end_device": "Sleepy end device",
|
||||||
|
"routing_end_device": "Routing end device",
|
||||||
|
"bridge": "Bridge",
|
||||||
|
"unknown": "Unknown"
|
||||||
|
},
|
||||||
|
"device_info": {
|
||||||
|
"device_info": "Device info",
|
||||||
|
"node_id": "Node ID",
|
||||||
|
"network_type": "Network Type",
|
||||||
|
"node_type": "Device type",
|
||||||
|
"network_name": "Network name",
|
||||||
|
"ip_adresses": "IP Address(es)",
|
||||||
|
"mac_address": "MAC address",
|
||||||
|
"available": "Available?"
|
||||||
|
},
|
||||||
|
"device_actions": {
|
||||||
|
"reinterview_device": "Re-interview device",
|
||||||
|
"ping_device": "Ping device",
|
||||||
|
"open_commissioning_window": "Enable commisisioning mode",
|
||||||
|
"manage_fabrics": "Manage fabrics",
|
||||||
|
"view_thread_network": "View Thread network"
|
||||||
|
},
|
||||||
|
"manage_fabrics": {
|
||||||
|
"title": "Connected fabrics",
|
||||||
|
"fabrics": "Manage the fabrics that have access to this device.",
|
||||||
|
"remove_fabric_confirm_header": "Remove {fabric} fabric from device",
|
||||||
|
"remove_fabric_confirm_text": "Are you sure you want to remove the {fabric} from the device? You will not be able to control/access the device from that ecosystem/fabric after this action!",
|
||||||
|
"remove_fabric_failed_header": "Remove {fabric} fabric failed",
|
||||||
|
"remove_fabric_failed_text": "The action did not succeed, check the logs for more information."
|
||||||
|
},
|
||||||
|
"reinterview_node": {
|
||||||
|
"title": "Re-interview a Matter device",
|
||||||
|
"introduction": "Perform a full re-interview of a Matter device. Use this feature only if your device has missing or incorrect functionality.",
|
||||||
|
"battery_device_warning": "You will need to wake battery powered devices before starting the re-interview. Refer to your device's manual for instructions on how to wake the device.",
|
||||||
|
"run_in_background": "You can close this dialog and the interview will continue in the background.",
|
||||||
|
"start_reinterview": "Start re-interview",
|
||||||
|
"in_progress": "The device is being interviewed. This may take some time.",
|
||||||
|
"interview_failed": "The device interview failed. Additional information may be available in the logs.",
|
||||||
|
"interview_complete": "Device interview complete."
|
||||||
|
},
|
||||||
|
"ping_node": {
|
||||||
|
"title": "Ping a Matter device",
|
||||||
|
"introduction": "Perform a (server-side) ping on your Matter device on all its (known) IP-addresses.",
|
||||||
|
"battery_device_warning": "Note that especially for battery powered devices this can take a a while. You may need to up powered devices before starting the pinging to speed up the process. Refer to your device's manual for instructions on how to wake the device.",
|
||||||
|
"start_ping": "Start ping",
|
||||||
|
"in_progress": "The device is being pinged. This may take some time.",
|
||||||
|
"ping_failed": "The device ping failed. Additional information may be available in the logs.",
|
||||||
|
"ping_complete": "Ping device complete."
|
||||||
|
},
|
||||||
|
"open_commissioning_window": {
|
||||||
|
"title": "Enable commissioning mode",
|
||||||
|
"introduction": "Enable commissioning mode on the device to pair it to another Matter controller.",
|
||||||
|
"start_commissioning": "Enable commissioning mode",
|
||||||
|
"in_progress": "We're communicating with the device. This may take some time.",
|
||||||
|
"failed": "The command failed. Additional information may be available in the logs.",
|
||||||
|
"sharing_code": "Sharing code"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tips": {
|
"tips": {
|
||||||
"tip": "Tip!",
|
"tip": "Tip!",
|
||||||
"join": "Join the community on our {forums}, {twitter}, {discord}, {blog} or {newsletter}",
|
"join": "Join the community on our {forums}, {twitter}, {discord}, {blog} or {newsletter}",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user