From 558f5232076544d3882d480e1e4ab8bf1291618a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 19 Jan 2023 03:35:33 -0500 Subject: [PATCH] Add initial Thread panel (#15126) * Add initial Thread panel * Add link to Matter panel --- src/data/thread.ts | 11 +++ src/panels/config/ha-panel-config.ts | 7 ++ .../integrations/ha-integration-card.ts | 1 + .../matter/matter-config-panel.ts | 26 +++++-- .../thread/thread-config-panel.ts | 73 +++++++++++++++++++ 5 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 src/data/thread.ts create mode 100644 src/panels/config/integrations/integration-panels/thread/thread-config-panel.ts diff --git a/src/data/thread.ts b/src/data/thread.ts new file mode 100644 index 0000000000..e58111ee12 --- /dev/null +++ b/src/data/thread.ts @@ -0,0 +1,11 @@ +import { HomeAssistant } from "../types"; + +export interface ThreadInfo { + url: string; + active_dataset_tlvs: string; +} + +export const threadGetInfo = (hass: HomeAssistant): Promise => + hass.callWS({ + type: "otbr/info", + }); diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts index 71c452a02c..6e3714bbfe 100644 --- a/src/panels/config/ha-panel-config.ts +++ b/src/panels/config/ha-panel-config.ts @@ -485,6 +485,13 @@ class HaPanelConfig extends HassRouterPage { "./integrations/integration-panels/matter/matter-config-panel" ), }, + thread: { + tag: "thread-config-panel", + load: () => + import( + "./integrations/integration-panels/thread/thread-config-panel" + ), + }, application_credentials: { tag: "ha-config-application-credentials", load: () => diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 5d3b7096c7..5fa1fba1d1 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -79,6 +79,7 @@ const integrationsWithPanel = { zha: "/config/zha/dashboard", zwave_js: "/config/zwave_js/dashboard", matter: "/config/matter", + otbr: "/config/thread", }; @customElement("ha-integration-card") diff --git a/src/panels/config/integrations/integration-panels/matter/matter-config-panel.ts b/src/panels/config/integrations/integration-panels/matter/matter-config-panel.ts index 77fa19ca74..eeb35d3e84 100644 --- a/src/panels/config/integrations/integration-panels/matter/matter-config-panel.ts +++ b/src/panels/config/integrations/integration-panels/matter/matter-config-panel.ts @@ -14,6 +14,7 @@ import { HomeAssistant } from "../../../../../types"; import "../../../../../components/ha-alert"; import { showPromptDialog } from "../../../../../dialogs/generic/show-dialog-box"; import { navigate } from "../../../../../common/navigate"; +import { isComponentLoaded } from "../../../../../common/config/is_component_loaded"; @customElement("matter-config-panel") export class MatterConfigPanel extends LitElement { @@ -32,18 +33,24 @@ export class MatterConfigPanel extends LitElement { protected render(): TemplateResult { return html` + ${isComponentLoaded(this.hass, "otbr") + ? html` + + Visit Thread Panel + + ` + : ""}
+ Matter is still in the early phase of development, it is not + meant to be used in production. This panel is for development + only.
${this._error ? html`${this._error}` : ""} - Matter is still in the early phase of development, it is not - meant to be used in production. This panel is for development - only. - You can add Matter devices by commissing them if they are not setup yet, or share them from another controller and enter the share code. @@ -199,6 +206,10 @@ export class MatterConfigPanel extends LitElement { static styles = [ haStyle, css` + ha-alert[alert-type="warning"] { + position: relative; + top: -16px; + } .content { padding: 24px 0 32px; max-width: 600px; @@ -208,6 +219,9 @@ export class MatterConfigPanel extends LitElement { ha-card:first-child { margin-bottom: 16px; } + a[slot="toolbar-icon"] { + text-decoration: none; + } `, ]; } diff --git a/src/panels/config/integrations/integration-panels/thread/thread-config-panel.ts b/src/panels/config/integrations/integration-panels/thread/thread-config-panel.ts new file mode 100644 index 0000000000..138318511e --- /dev/null +++ b/src/panels/config/integrations/integration-panels/thread/thread-config-panel.ts @@ -0,0 +1,73 @@ +import "@material/mwc-button"; +import { css, html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import "../../../../../components/ha-card"; +import "../../../../../layouts/hass-subpage"; +import { haStyle } from "../../../../../resources/styles"; +import { HomeAssistant } from "../../../../../types"; +import { threadGetInfo, ThreadInfo } from "../../../../../data/thread"; + +@customElement("thread-config-panel") +export class ThreadConfigPanel extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ type: Boolean }) public narrow!: boolean; + + @state() private _info?: ThreadInfo; + + protected render(): TemplateResult { + return html` + +
+ +
+ ${!this._info + ? html`` + : html` + + + + + + + + + +
URL${this._info.url}
Active Dataset TLVs${this._info.active_dataset_tlvs || "-"}
+ `} +
+
+
+
+ `; + } + + protected override firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + + threadGetInfo(this.hass).then((info) => { + this._info = info; + }); + } + + static styles = [ + haStyle, + css` + .content { + padding: 24px 0 32px; + max-width: 600px; + margin: 0 auto; + direction: ltr; + } + ha-card:first-child { + margin-bottom: 16px; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "thread-config-panel": ThreadConfigPanel; + } +}