Allow to set default router for thread network (#17584)

* Allow to set default router for thread network

* Update thread-config-panel.ts
This commit is contained in:
Bram Kragten 2023-08-16 11:52:42 +02:00 committed by GitHub
parent 9f0b9782a0
commit 2c17d2fead
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 131 additions and 57 deletions

View File

@ -103,3 +103,14 @@ export const setPreferredThreadDataSet = (
type: "thread/set_preferred_dataset", type: "thread/set_preferred_dataset",
dataset_id, dataset_id,
}); });
export const setPreferredBorderAgent = (
hass: HomeAssistant,
dataset_id: string,
border_agent_id: string
): Promise<void> =>
hass.callWS({
type: "thread/set_preferred_border_agent_id",
dataset_id,
border_agent_id,
});

View File

@ -5,31 +5,35 @@ import {
mdiDevices, mdiDevices,
mdiDotsVertical, mdiDotsVertical,
mdiInformationOutline, mdiInformationOutline,
mdiStar,
} from "@mdi/js"; } from "@mdi/js";
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit"; import { LitElement, PropertyValues, TemplateResult, css, html } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../../../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../../../../common/config/is_component_loaded";
import { stringCompare } from "../../../../../common/string/compare"; import { stringCompare } from "../../../../../common/string/compare";
import { extractSearchParam } from "../../../../../common/url/search-params"; import { extractSearchParam } from "../../../../../common/url/search-params";
import "../../../../../components/ha-button-menu";
import "../../../../../components/ha-list-item";
import "../../../../../components/ha-card"; import "../../../../../components/ha-card";
import { getSignedPath } from "../../../../../data/auth"; import { getSignedPath } from "../../../../../data/auth";
import { getConfigEntryDiagnosticsDownloadUrl } from "../../../../../data/diagnostics"; import { getConfigEntryDiagnosticsDownloadUrl } from "../../../../../data/diagnostics";
import { import {
getOTBRInfo,
OTBRCreateNetwork, OTBRCreateNetwork,
OTBRInfo, OTBRInfo,
OTBRSetChannel, OTBRSetChannel,
OTBRSetNetwork, OTBRSetNetwork,
getOTBRInfo,
} from "../../../../../data/otbr"; } from "../../../../../data/otbr";
import { import {
ThreadDataSet,
ThreadRouter,
addThreadDataSet, addThreadDataSet,
listThreadDataSets, listThreadDataSets,
removeThreadDataSet, removeThreadDataSet,
setPreferredBorderAgent,
setPreferredThreadDataSet, setPreferredThreadDataSet,
subscribeDiscoverThreadRouters, subscribeDiscoverThreadRouters,
ThreadDataSet,
ThreadRouter,
} from "../../../../../data/thread"; } from "../../../../../data/thread";
import { showConfigFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-config-flow"; import { showConfigFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-config-flow";
import { import {
@ -160,35 +164,47 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
})} })}
</h4> </h4>
</div> </div>
${network.routers.map( ${network.routers.map((router) => {
(router) => const showOverflow =
html`<ha-list-item ("dataset" in network && router.border_agent_id) ||
class="router" router.extended_address === this._otbrInfo?.extended_address;
twoline return html`<ha-list-item
graphic="avatar" class="router"
.hasMeta=${router.extended_address === twoline
this._otbrInfo?.extended_address} graphic="avatar"
> .hasMeta=${showOverflow}
<img >
slot="graphic" <img
.src=${brandsUrl({ slot="graphic"
domain: router.brand, .src=${brandsUrl({
brand: true, domain: router.brand,
type: "icon", brand: true,
darkOptimized: this.hass.themes?.darkMode, type: "icon",
})} darkOptimized: this.hass.themes?.darkMode,
alt=${router.brand} })}
referrerpolicy="no-referrer" alt=${router.brand}
@error=${this._onImageError} referrerpolicy="no-referrer"
@load=${this._onImageLoad} @error=${this._onImageError}
/> @load=${this._onImageLoad}
${router.model_name || />
router.server?.replace(".local.", "") || ${router.model_name ||
""} router.server?.replace(".local.", "") ||
<span slot="secondary">${router.server}</span> ""}
${router.extended_address === this._otbrInfo?.extended_address <span slot="secondary">${router.server}</span>
? html`<ha-button-menu ${showOverflow
? html`${network.dataset &&
router.border_agent_id ===
network.dataset.preferred_border_agent_id
? html`<ha-svg-icon .path=${mdiStar} slot="meta">
${this.hass.localize(
"ui.panel.config.thread.default_router"
)}
</ha-svg-icon>`
: ""}
<ha-button-menu
slot="meta" slot="meta"
.network=${network}
.router=${router}
@action=${this._handleRouterAction} @action=${this._handleRouterAction}
> >
<ha-icon-button <ha-icon-button
@ -197,27 +213,46 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
)} )}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
slot="trigger" slot="trigger"
></ha-icon-button ></ha-icon-button>
><ha-list-item ${network.dataset && router.border_agent_id
>${this.hass.localize( ? html`<ha-list-item
"ui.panel.config.thread.reset_border_router" .disabled=${router.border_agent_id ===
)}</ha-list-item network.dataset.preferred_border_agent_id}
><ha-list-item >
>${this.hass.localize( ${router.border_agent_id ===
"ui.panel.config.thread.change_channel" network.dataset.preferred_border_agent_id
)}</ha-list-item ? this.hass.localize(
>${network.dataset?.preferred "ui.panel.config.thread.default_router"
? "" )
: html`<ha-list-item : this.hass.localize(
>${this.hass.localize( "ui.panel.config.thread.set_default_router"
"ui.panel.config.thread.add_to_my_network" )}
)}</ha-list-item </ha-list-item>`
></ha-button-menu : ""}
>`}</ha-button-menu ${router.extended_address ===
>` this._otbrInfo?.extended_address
: ""} ? html`<ha-list-item>
</ha-list-item>` ${this.hass.localize(
)}` "ui.panel.config.thread.reset_border_router"
)}</ha-list-item
>
<ha-list-item>
${this.hass.localize(
"ui.panel.config.thread.change_channel"
)}</ha-list-item
>
${network.dataset?.preferred
? ""
: html`<ha-list-item>
${this.hass.localize(
"ui.panel.config.thread.add_to_my_network"
)}
</ha-list-item>`}`
: ""}
</ha-button-menu>`
: ""}
</ha-list-item>`;
})}`
: html`<div class="card-content no-routers"> : html`<div class="card-content no-routers">
<ha-svg-icon .path=${mdiDevices}></ha-svg-icon> <ha-svg-icon .path=${mdiDevices}></ha-svg-icon>
${network.dataset?.extended_pan_id && ${network.dataset?.extended_pan_id &&
@ -382,14 +417,23 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
} }
private _handleRouterAction(ev: CustomEvent<ActionDetail>) { private _handleRouterAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) { const network = (ev.currentTarget as any).network as ThreadNetwork;
const router = (ev.currentTarget as any).router as ThreadRouter;
const index =
network.dataset && router.border_agent_id
? Number(ev.detail.index)
: Number(ev.detail.index) + 1;
switch (index) {
case 0: case 0:
this._resetBorderRouter(); this._setPreferredBorderAgent(network.dataset!, router);
break; break;
case 1: case 1:
this._changeChannel(); this._resetBorderRouter();
break; break;
case 2: case 2:
this._changeChannel();
break;
case 3:
this._setDataset(); this._setDataset();
break; break;
} }
@ -452,6 +496,19 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
this._refresh(); this._refresh();
} }
private async _setPreferredBorderAgent(
dataset: ThreadDataSet,
router: ThreadRouter
) {
const datasetId = dataset.dataset_id;
const borderAgentId = router.border_agent_id;
if (!borderAgentId) {
return;
}
await setPreferredBorderAgent(this.hass, datasetId, borderAgentId);
this._refresh();
}
private async _addTLV() { private async _addTLV() {
const tlv = await showPromptDialog(this, { const tlv = await showPromptDialog(this, {
title: this.hass.localize("ui.panel.config.thread.add_dataset"), title: this.hass.localize("ui.panel.config.thread.add_dataset"),
@ -571,11 +628,15 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
direction: ltr; direction: ltr;
} }
ha-list-item.router { ha-list-item.router {
--mdc-list-item-meta-size: auto;
--mdc-list-item-meta-display: flex;
--mdc-list-side-padding: 16px; --mdc-list-side-padding: 16px;
--mdc-list-item-meta-size: 48px;
cursor: default; cursor: default;
overflow: visible; overflow: visible;
} }
ha-svg-icon[slot="meta"] {
width: 24px;
}
ha-button-menu a { ha-button-menu a {
text-decoration: none; text-decoration: none;
} }

View File

@ -3707,6 +3707,8 @@
"add_open_thread_border_router": "Add an OpenThread border router", "add_open_thread_border_router": "Add an OpenThread border router",
"reset_border_router": "Reset border router", "reset_border_router": "Reset border router",
"add_to_my_network": "Add to preferred network", "add_to_my_network": "Add to preferred network",
"default_router": "Default router for network",
"set_default_router": "Set as default router for network",
"no_routers_otbr_network": "No border routers where found, maybe the border router is not configured correctly. You can try to reset it to the factory settings.", "no_routers_otbr_network": "No border routers where found, maybe the border router is not configured correctly. You can try to reset it to the factory settings.",
"add_dataset_from_tlv": "Add dataset from TLV", "add_dataset_from_tlv": "Add dataset from TLV",
"add_dataset": "Add Thread dataset", "add_dataset": "Add Thread dataset",