diff --git a/src/data/otbr.ts b/src/data/otbr.ts index 93e77a1eda..154d2863ff 100644 --- a/src/data/otbr.ts +++ b/src/data/otbr.ts @@ -3,6 +3,7 @@ import { HomeAssistant } from "../types"; export interface OTBRInfo { url: string; active_dataset_tlvs: string; + channel: number; } export const getOTBRInfo = (hass: HomeAssistant): Promise => @@ -30,3 +31,12 @@ export const OTBRGetExtendedAddress = ( hass.callWS({ type: "otbr/get_extended_address", }); + +export const OTBRSetChannel = ( + hass: HomeAssistant, + channel: number +): Promise<{ delay: number }> => + hass.callWS({ + type: "otbr/set_channel", + channel, + }); 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 27defda51a..2fdea52d73 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 @@ -20,6 +20,7 @@ import { OTBRCreateNetwork, OTBRGetExtendedAddress, OTBRInfo, + OTBRSetChannel, OTBRSetNetwork, } from "../../../../../data/otbr"; import { @@ -200,6 +201,10 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) { >${this.hass.localize( "ui.panel.config.thread.reset_border_router" )}${this.hass.localize( + "ui.panel.config.thread.change_channel" + )}${network.dataset?.preferred ? "" : html` 26) { + showAlertDialog(this, { + title: this.hass.localize( + "ui.panel.config.thread.change_channel_invalid" + ), + text: this.hass.localize("ui.panel.config.thread.change_channel_range"), + }); + return; + } + try { + const result = await OTBRSetChannel(this.hass, channel); + showAlertDialog(this, { + title: this.hass.localize( + "ui.panel.config.thread.change_channel_initiated_title" + ), + text: this.hass.localize( + "ui.panel.config.thread.change_channel_initiated_text", + { delay: Math.floor(result.delay / 60) } + ), + }); + } catch (err: any) { + if (err.code === "multiprotocol_enabled") { + showAlertDialog(this, { + title: this.hass.localize( + "ui.panel.config.thread.change_channel_multiprotocol_enabled_title" + ), + text: this.hass.localize( + "ui.panel.config.thread.change_channel_multiprotocol_enabled_text" + ), + }); + return; + } + showAlertDialog(this, { + title: "Error", + text: err.message || err, + }); + } + this._refresh(); + } + static styles = [ haStyle, css` diff --git a/src/translations/en.json b/src/translations/en.json index 714d2343ba..7d80346d89 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3684,7 +3684,16 @@ "no_border_routers": "No border routers found", "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" + "operational_dataset": "Operational dataset", + "change_channel": "Change channel", + "change_channel_initiated_title": "Channel change in progress", + "change_channel_initiated_text": "The channel change has been initiated and will complete in {delay} minutes.", + "change_channel_invalid": "Invalid channel", + "change_channel_label": "Channel", + "change_channel_multiprotocol_enabled_title": "The Thread radio has multiprotocol enabled", + "change_channel_multiprotocol_enabled_text": "To change channel when the Thread radio has multiprotocol enabled, please use the hardware settings menu.", + "change_channel_range": "Channel must be in the range 11 to 26", + "change_channel_text": "Initiate a channel change for your Thread networks. This is an advanced operation and can leave your Thread networks inoperable if the new channel is congested. Depending on existing network conditions, many of your devices may not migrate to the new channel and will require re-joining before they start working again. Use with caution." }, "zha": { "common": {