diff --git a/src/data/thread.ts b/src/data/thread.ts index 82c19fbe03..d999690a68 100644 --- a/src/data/thread.ts +++ b/src/data/thread.ts @@ -18,7 +18,7 @@ export interface ThreadDataSet { channel: number | null; created: string; dataset_id: string; - extended_pan_id: string | null; + extended_pan_id: string; network_name: string; pan_id: string | null; preferred_border_agent_id: string | null; diff --git a/src/external_app/external_messaging.ts b/src/external_app/external_messaging.ts index e8a436e203..5e0461585b 100644 --- a/src/external_app/external_messaging.ts +++ b/src/external_app/external_messaging.ts @@ -141,9 +141,10 @@ interface EMOutgoingMessageImprovScan extends EMMessage { interface EMOutgoingMessageThreadStoreInPlatformKeychain extends EMMessage { type: "thread/store_in_platform_keychain"; payload: { - mac_extended_address: string; - border_agent_id: string; + mac_extended_address: string | null; + border_agent_id: string | null; active_operational_dataset: string; + extended_pan_id: string; }; } 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 index 23dfce2198..206ab96194 100644 --- a/src/panels/config/integrations/integration-panels/thread/thread-config-panel.ts +++ b/src/panels/config/integrations/integration-panels/thread/thread-config-panel.ts @@ -37,6 +37,7 @@ import { ThreadDataSet, ThreadRouter, addThreadDataSet, + getThreadDataSetTLV, listThreadDataSets, removeThreadDataSet, setPreferredBorderAgent, @@ -168,8 +169,7 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) { (otbr) => otbr.extended_pan_id === network.dataset!.extended_pan_id )); const canImportKeychain = - this.hass.auth.external?.config.canTransferThreadCredentialsToKeychain && - otbrForNetwork; + this.hass.auth.external?.config.canTransferThreadCredentialsToKeychain; return html`
@@ -208,8 +208,12 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) { ${network.routers.map((router) => { const otbr = this._otbrInfo && this._otbrInfo[router.extended_address]; - const showOverflow = - ("dataset" in network && router.border_agent_id) || otbr; + const showDefaultRouter = !!network.dataset; + const isDefaultRouter = + showDefaultRouter && + router.extended_address === + network.dataset!.preferred_extended_address; + const showOverflow = showDefaultRouter || otbr; return html`${router.server} ${showOverflow - ? html`${network.dataset && - router.extended_address === - network.dataset.preferred_extended_address + ? html`${isDefaultRouter ? html` - ${network.dataset && router.border_agent_id - ? html` - ${router.border_agent_id === - network.dataset.preferred_border_agent_id + ${showDefaultRouter + ? html` + ${isDefaultRouter ? this.hass.localize( "ui.panel.config.thread.default_router" ) @@ -321,9 +319,13 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) { >
` : ""} - ${canImportKeychain + ${canImportKeychain && + network.dataset?.preferred && + network.routers?.length ? html`
- Send credentials to phone
` @@ -331,17 +333,30 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
`; } - private _sendCredentials(ev) { - const otbr = (ev.currentTarget as any).otbr as OTBRInfo; - if (!otbr) { + private async _sendCredentials(ev) { + const dataset = (ev.currentTarget as any).networkDataset as ThreadDataSet; + if (!dataset) { + return; + } + if ( + !dataset.preferred_extended_address && + !dataset.preferred_border_agent_id + ) { + showAlertDialog(this, { + title: "Error", + text: this.hass.localize("ui.panel.config.thread.no_preferred_router"), + }); return; } this.hass.auth.external!.fireMessage({ type: "thread/store_in_platform_keychain", payload: { - mac_extended_address: otbr.extended_address, - border_agent_id: otbr.border_agent_id, - active_operational_dataset: otbr.active_dataset_tlvs, + mac_extended_address: dataset.preferred_extended_address, + border_agent_id: dataset.preferred_border_agent_id, + active_operational_dataset: ( + await getThreadDataSetTLV(this.hass, dataset.dataset_id) + ).tlv, + extended_pan_id: dataset.extended_pan_id, }, }); } @@ -467,10 +482,7 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) { const network = (ev.currentTarget as any).network as ThreadNetwork; const router = (ev.currentTarget as any).router as ThreadRouter; const otbr = (ev.currentTarget as any).otbr as OTBRInfo; - const index = - network.dataset && router.border_agent_id - ? Number(ev.detail.index) - : Number(ev.detail.index) + 1; + const index = Number(ev.detail.index); switch (index) { case 0: this._setPreferredBorderAgent(network.dataset!, router); diff --git a/src/translations/en.json b/src/translations/en.json index 32c55ddef7..92d5b38048 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4590,6 +4590,7 @@ "confirm_delete_dataset": "Delete {name} dataset?", "confirm_delete_dataset_text": "This network will be removed from Home Assistant.", "no_border_routers": "No border routers found", + "no_preferred_router": "No preferred border router defined", "border_routers": "{count} border {count, plural,\n one {router}\n other {routers}\n}", "managed_by_home_assistant": "Managed by Home Assistant", "operational_dataset": "Operational dataset",