mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-24 21:37:21 +00:00
Add migration wizard for zwave -> zwave_js (#10097)
This commit is contained in:
parent
a89da0dac0
commit
8721776839
@ -73,14 +73,6 @@ export interface OZWDeviceConfig {
|
||||
help: string;
|
||||
}
|
||||
|
||||
export interface OZWMigrationData {
|
||||
migration_device_map: Record<string, string>;
|
||||
zwave_entity_ids: string[];
|
||||
ozw_entity_ids: string[];
|
||||
migration_entity_map: Record<string, string>;
|
||||
migrated: boolean;
|
||||
}
|
||||
|
||||
export const nodeQueryStages = [
|
||||
"ProtocolInfo",
|
||||
"Probe",
|
||||
@ -219,12 +211,3 @@ export const refreshNodeInfo = (
|
||||
ozw_instance,
|
||||
node_id,
|
||||
});
|
||||
|
||||
export const migrateZwave = (
|
||||
hass: HomeAssistant,
|
||||
dry_run = true
|
||||
): Promise<OZWMigrationData> =>
|
||||
hass.callWS({
|
||||
type: "ozw/migrate_zwave",
|
||||
dry_run,
|
||||
});
|
||||
|
@ -60,11 +60,11 @@ export const fetchNetworkStatus = (
|
||||
type: "zwave/network_status",
|
||||
});
|
||||
|
||||
export const startOzwConfigFlow = (
|
||||
export const startZwaveJsConfigFlow = (
|
||||
hass: HomeAssistant
|
||||
): Promise<{ flow_id: string }> =>
|
||||
hass.callWS({
|
||||
type: "zwave/start_ozw_config_flow",
|
||||
type: "zwave/start_zwave_js_config_flow",
|
||||
});
|
||||
|
||||
export const fetchMigrationConfig = (
|
||||
|
@ -174,6 +174,25 @@ export interface RequestedGrant {
|
||||
|
||||
export const nodeStatus = ["unknown", "asleep", "awake", "dead", "alive"];
|
||||
|
||||
export interface ZWaveJsMigrationData {
|
||||
migration_device_map: Record<string, string>;
|
||||
zwave_entity_ids: string[];
|
||||
zwave_js_entity_ids: string[];
|
||||
migration_entity_map: Record<string, string>;
|
||||
migrated: boolean;
|
||||
}
|
||||
|
||||
export const migrateZwave = (
|
||||
hass: HomeAssistant,
|
||||
entry_id: string,
|
||||
dry_run = true
|
||||
): Promise<ZWaveJsMigrationData> =>
|
||||
hass.callWS({
|
||||
type: "zwave_js/migrate_zwave",
|
||||
entry_id,
|
||||
dry_run,
|
||||
});
|
||||
|
||||
export const fetchNetworkStatus = (
|
||||
hass: HomeAssistant,
|
||||
entry_id: string
|
||||
@ -307,8 +326,8 @@ export const reinterviewNode = (
|
||||
(message: any) => callbackFunction(message),
|
||||
{
|
||||
type: "zwave_js/refresh_node_info",
|
||||
entry_id: entry_id,
|
||||
node_id: node_id,
|
||||
entry_id,
|
||||
node_id,
|
||||
}
|
||||
);
|
||||
|
||||
@ -319,8 +338,8 @@ export const healNode = (
|
||||
): Promise<boolean> =>
|
||||
hass.callWS({
|
||||
type: "zwave_js/heal_node",
|
||||
entry_id: entry_id,
|
||||
node_id: node_id,
|
||||
entry_id,
|
||||
node_id,
|
||||
});
|
||||
|
||||
export const removeFailedNode = (
|
||||
@ -333,8 +352,8 @@ export const removeFailedNode = (
|
||||
(message: any) => callbackFunction(message),
|
||||
{
|
||||
type: "zwave_js/remove_failed_node",
|
||||
entry_id: entry_id,
|
||||
node_id: node_id,
|
||||
entry_id,
|
||||
node_id,
|
||||
}
|
||||
);
|
||||
|
||||
@ -344,7 +363,7 @@ export const healNetwork = (
|
||||
): Promise<UnsubscribeFunc> =>
|
||||
hass.callWS({
|
||||
type: "zwave_js/begin_healing_network",
|
||||
entry_id: entry_id,
|
||||
entry_id,
|
||||
});
|
||||
|
||||
export const stopHealNetwork = (
|
||||
@ -353,9 +372,24 @@ export const stopHealNetwork = (
|
||||
): Promise<UnsubscribeFunc> =>
|
||||
hass.callWS({
|
||||
type: "zwave_js/stop_healing_network",
|
||||
entry_id: entry_id,
|
||||
entry_id,
|
||||
});
|
||||
|
||||
export const subscribeNodeReady = (
|
||||
hass: HomeAssistant,
|
||||
entry_id: string,
|
||||
node_id: number,
|
||||
callbackFunction: (message) => void
|
||||
): Promise<UnsubscribeFunc> =>
|
||||
hass.connection.subscribeMessage(
|
||||
(message: any) => callbackFunction(message),
|
||||
{
|
||||
type: "zwave_js/node_ready",
|
||||
entry_id,
|
||||
node_id,
|
||||
}
|
||||
);
|
||||
|
||||
export const subscribeHealNetworkProgress = (
|
||||
hass: HomeAssistant,
|
||||
entry_id: string,
|
||||
@ -365,7 +399,7 @@ export const subscribeHealNetworkProgress = (
|
||||
(message: any) => callbackFunction(message),
|
||||
{
|
||||
type: "zwave_js/subscribe_heal_network_progress",
|
||||
entry_id: entry_id,
|
||||
entry_id,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -104,28 +104,14 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
<ha-config-section is-wide="[[isWide]]">
|
||||
<ha-card
|
||||
class="content"
|
||||
header="[[localize('ui.panel.config.zwave.migration.ozw.header')]]"
|
||||
header="[[localize('ui.panel.config.zwave.migration.zwave_js.header')]]"
|
||||
>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
If you are experiencing problems with your Z-Wave devices, you
|
||||
can migrate to the newer OZW integration, that is currently in
|
||||
beta.
|
||||
</p>
|
||||
<p>
|
||||
Be aware that the future of OZW is not guaranteed, as the
|
||||
development has stopped.
|
||||
</p>
|
||||
<p>
|
||||
If you are currently not experiencing issues with your Z-Wave
|
||||
devices, we recommend you to wait for the successor of the OZW
|
||||
integration, Z-Wave JS, that is in active development at the
|
||||
moment.
|
||||
</p>
|
||||
[[localize('ui.panel.config.zwave.migration.zwave_js.introduction')]]
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<a href="/config/zwave/migration"
|
||||
><mwc-button>Start Migration to OZW</mwc-button></a
|
||||
><mwc-button>Start Migration to Z-Wave JS</mwc-button></a
|
||||
>
|
||||
</div>
|
||||
</ha-card>
|
||||
|
@ -6,7 +6,6 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { isComponentLoaded } from "../../../../../common/config/is_component_loaded";
|
||||
import { computeStateName } from "../../../../../common/entity/compute_state_name";
|
||||
import { navigate } from "../../../../../common/navigate";
|
||||
import "../../../../../components/buttons/ha-call-api-button";
|
||||
import "../../../../../components/buttons/ha-call-service-button";
|
||||
import "../../../../../components/ha-card";
|
||||
@ -15,16 +14,25 @@ import "../../../../../components/ha-icon";
|
||||
import "../../../../../components/ha-icon-button";
|
||||
import {
|
||||
computeDeviceName,
|
||||
DeviceRegistryEntry,
|
||||
fetchDeviceRegistry,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../../../data/device_registry";
|
||||
import { migrateZwave, OZWMigrationData } from "../../../../../data/ozw";
|
||||
import {
|
||||
migrateZwave,
|
||||
ZWaveJsMigrationData,
|
||||
fetchNetworkStatus as fetchZwaveJsNetworkStatus,
|
||||
fetchNodeStatus,
|
||||
getIdentifiersFromDevice,
|
||||
subscribeNodeReady,
|
||||
} from "../../../../../data/zwave_js";
|
||||
import {
|
||||
fetchMigrationConfig,
|
||||
fetchNetworkStatus,
|
||||
startOzwConfigFlow,
|
||||
startZwaveJsConfigFlow,
|
||||
ZWaveMigrationConfig,
|
||||
ZWaveNetworkStatus,
|
||||
ZWAVE_NETWORK_STATE_STOPPED,
|
||||
fetchNetworkStatus,
|
||||
} from "../../../../../data/zwave";
|
||||
import { showConfigFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-config-flow";
|
||||
import { showAlertDialog } from "../../../../../dialogs/generic/show-dialog-box";
|
||||
@ -32,6 +40,8 @@ import "../../../../../layouts/hass-subpage";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import "../../../ha-config-section";
|
||||
import { computeStateDomain } from "../../../../../common/entity/compute_state_domain";
|
||||
import "../../../../../components/ha-alert";
|
||||
|
||||
@customElement("zwave-migration")
|
||||
export class ZwaveMigration extends LitElement {
|
||||
@ -51,12 +61,18 @@ export class ZwaveMigration extends LitElement {
|
||||
|
||||
@state() private _migrationConfig?: ZWaveMigrationConfig;
|
||||
|
||||
@state() private _migrationData?: OZWMigrationData;
|
||||
@state() private _migrationData?: ZWaveJsMigrationData;
|
||||
|
||||
@state() private _migratedZwaveEntities?: string[];
|
||||
|
||||
@state() private _deviceNameLookup: { [id: string]: string } = {};
|
||||
|
||||
@state() private _waitingOnDevices?: DeviceRegistryEntry[];
|
||||
|
||||
private _zwaveJsEntryId?: string;
|
||||
|
||||
private _nodeReadySubscriptions?: Promise<UnsubscribeFunc>[];
|
||||
|
||||
private _unsub?: Promise<UnsubscribeFunc>;
|
||||
|
||||
private _unsubDevices?: UnsubscribeFunc;
|
||||
@ -79,259 +95,272 @@ export class ZwaveMigration extends LitElement {
|
||||
>
|
||||
<ha-config-section .narrow=${this.narrow} .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${this.hass.localize("ui.panel.config.zwave.migration.ozw.header")}
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave.migration.zwave_js.header"
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave.migration.ozw.introduction"
|
||||
"ui.panel.config.zwave.migration.zwave_js.introduction"
|
||||
)}
|
||||
</div>
|
||||
${!isComponentLoaded(this.hass, "hassio") &&
|
||||
!isComponentLoaded(this.hass, "mqtt")
|
||||
? html`
|
||||
<ha-card class="content" header="MQTT Required">
|
||||
${html`
|
||||
${this._step === 0
|
||||
? html`
|
||||
<ha-card class="content" header="Introduction">
|
||||
<div class="card-content">
|
||||
<p>
|
||||
This wizard will walk through the following steps to
|
||||
migrate from the legacy Z-Wave integration to Z-Wave JS.
|
||||
</p>
|
||||
<ol>
|
||||
<li>Stop the Z-Wave network</li>
|
||||
${!isComponentLoaded(this.hass, "hassio")
|
||||
? html`<li>Configure and start Z-Wave JS</li>`
|
||||
: ""}
|
||||
<li>Set up the Z-Wave JS integration</li>
|
||||
<li>
|
||||
Migrate entities and devices to the new integration
|
||||
</li>
|
||||
<li>Remove legacy Z-Wave integration</li>
|
||||
</ol>
|
||||
<p>
|
||||
<b>
|
||||
${isComponentLoaded(this.hass, "hassio")
|
||||
? html`Please
|
||||
<a href="/hassio/backups">make a backup</a>
|
||||
before proceeding.`
|
||||
: "Please make a backup of your installation before proceeding."}
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._continue}>
|
||||
Continue
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: this._step === 1
|
||||
? html`
|
||||
<ha-card class="content" header="Stop Z-Wave Network">
|
||||
<div class="card-content">
|
||||
<p>
|
||||
We need to stop the Z-Wave network to perform the
|
||||
migration. Home Assistant will not be able to control
|
||||
Z-Wave devices while the network is stopped.
|
||||
</p>
|
||||
${Object.values(this.hass.states)
|
||||
.filter(
|
||||
(entityState) =>
|
||||
computeStateDomain(entityState) === "zwave" &&
|
||||
entityState.state !== "ready"
|
||||
)
|
||||
.map(
|
||||
(entityState) =>
|
||||
html`<ha-alert alert-type="warning">
|
||||
Device ${computeStateName(entityState)}
|
||||
(${entityState.entity_id}) is not ready yet! For
|
||||
the best result, wake the device up if it is
|
||||
battery powered and wait for this device to become
|
||||
ready.
|
||||
</ha-alert>`
|
||||
)}
|
||||
${this._stoppingNetwork
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress
|
||||
active
|
||||
></ha-circular-progress>
|
||||
<div><p>Stopping Z-Wave Network...</p></div>
|
||||
</div>
|
||||
`
|
||||
: ``}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._stopNetwork}>
|
||||
Stop Network
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: this._step === 2
|
||||
? html`
|
||||
<ha-card class="content" header="Set up Z-Wave JS">
|
||||
<div class="card-content">
|
||||
<p>Now it's time to set up the Z-Wave JS integration.</p>
|
||||
${isComponentLoaded(this.hass, "hassio")
|
||||
? html`
|
||||
<p>
|
||||
Z-Wave JS runs as a Home Assistant add-on that
|
||||
will be setup next. Make sure to check the
|
||||
checkbox to use the add-on.
|
||||
</p>
|
||||
`
|
||||
: html`
|
||||
<p>
|
||||
You are not running Home Assistant OS (the default
|
||||
installation type) or Home Assistant Supervised,
|
||||
so we can not setup Z-Wave JS automaticaly. Follow
|
||||
the
|
||||
<a
|
||||
href="https://www.home-assistant.io/integrations/zwave_js/#advanced-installation-instructions"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>advanced installation instructions</a
|
||||
>
|
||||
to install Z-Wave JS.
|
||||
</p>
|
||||
<p>
|
||||
Here's the current Z-Wave configuration. You'll
|
||||
need these values when setting up Z-Wave JS.
|
||||
</p>
|
||||
${this._migrationConfig
|
||||
? html`<blockquote>
|
||||
USB Path: ${this._migrationConfig.usb_path}<br />
|
||||
Network Key:
|
||||
${this._migrationConfig.network_key}
|
||||
</blockquote>`
|
||||
: ``}
|
||||
<p>
|
||||
Once Z-Wave JS is installed and running, click
|
||||
'Continue' to set up the Z-Wave JS integration and
|
||||
migrate your devices and entities.
|
||||
</p>
|
||||
`}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._setupZwaveJs}>
|
||||
Continue
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: this._step === 3
|
||||
? html`
|
||||
<ha-card
|
||||
class="content"
|
||||
header="Migrate devices and entities"
|
||||
>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
Now it's time to migrate your devices and entities from
|
||||
the legacy Z-Wave integration to the Z-Wave JS
|
||||
integration, to make sure all your UI's and automations
|
||||
keep working.
|
||||
</p>
|
||||
${this._waitingOnDevices?.map(
|
||||
(device) =>
|
||||
html`<ha-alert alert-type="warning">
|
||||
Device ${computeDeviceName(device, this.hass)} is
|
||||
not ready yet! For the best result, wake the device
|
||||
up if it is battery powered and wait for this device
|
||||
to become ready.
|
||||
</ha-alert>`
|
||||
)}
|
||||
${this._migrationData
|
||||
? html`
|
||||
<p>Below is a list of what will be migrated.</p>
|
||||
${this._migratedZwaveEntities!.length !==
|
||||
this._migrationData.zwave_entity_ids.length
|
||||
? html`<ha-alert
|
||||
alert-type="warning"
|
||||
title="Not all entities can be migrated!"
|
||||
>
|
||||
The following entities will not be migrated
|
||||
and might need manual adjustments to your
|
||||
config:
|
||||
</ha-alert>
|
||||
<ul>
|
||||
${this._migrationData.zwave_entity_ids.map(
|
||||
(entity_id) =>
|
||||
!this._migratedZwaveEntities!.includes(
|
||||
entity_id
|
||||
)
|
||||
? html`<li>
|
||||
${entity_id in this.hass.states
|
||||
? computeStateName(
|
||||
this.hass.states[entity_id]
|
||||
)
|
||||
: ""}
|
||||
(${entity_id})
|
||||
</li>`
|
||||
: ""
|
||||
)}
|
||||
</ul>`
|
||||
: ""}
|
||||
${Object.keys(
|
||||
this._migrationData.migration_device_map
|
||||
).length
|
||||
? html`<h3>Devices that will be migrated:</h3>
|
||||
<ul>
|
||||
${Object.keys(
|
||||
this._migrationData.migration_device_map
|
||||
).map(
|
||||
(device_id) =>
|
||||
html`<li>
|
||||
${this._deviceNameLookup[device_id] ||
|
||||
device_id}
|
||||
</li>`
|
||||
)}
|
||||
</ul>`
|
||||
: ""}
|
||||
${Object.keys(
|
||||
this._migrationData.migration_entity_map
|
||||
).length
|
||||
? html`<h3>Entities that will be migrated:</h3>
|
||||
<ul>
|
||||
${Object.keys(
|
||||
this._migrationData.migration_entity_map
|
||||
).map(
|
||||
(entity_id) => html`<li>
|
||||
${entity_id in this.hass.states
|
||||
? computeStateName(
|
||||
this.hass.states[entity_id]
|
||||
)
|
||||
: ""}
|
||||
(${entity_id})
|
||||
</li>`
|
||||
)}
|
||||
</ul>`
|
||||
: ""}
|
||||
`
|
||||
: html` <div class="flex-container">
|
||||
<p>Loading migration data...</p>
|
||||
<ha-circular-progress active>
|
||||
</ha-circular-progress>
|
||||
</div>`}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._doMigrate}>
|
||||
Migrate
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: this._step === 4
|
||||
? html`<ha-card class="content" header="Done!">
|
||||
<div class="card-content">
|
||||
That was all! You are now migrated to the new Z-Wave JS
|
||||
integration, check if all your devices and entities are back
|
||||
the way they where, if not all entities could be migrated
|
||||
you might have to change those manually.
|
||||
<p>
|
||||
OpenZWave requires MQTT. Please setup an MQTT broker and
|
||||
the MQTT integration to proceed with the migration.
|
||||
If you have 'zwave' in your configurtion.yaml file, you
|
||||
should remove it now.
|
||||
</p>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: html`
|
||||
${this._step === 0
|
||||
? html`
|
||||
<ha-card class="content" header="Introduction">
|
||||
<div class="card-content">
|
||||
<p>
|
||||
This wizard will walk through the following steps to
|
||||
migrate from the legacy Z-Wave integration to
|
||||
OpenZWave.
|
||||
</p>
|
||||
<ol>
|
||||
<li>Stop the Z-Wave network</li>
|
||||
<li>
|
||||
<i
|
||||
>If running Home Assistant Core in Docker or in
|
||||
Python venv:</i
|
||||
>
|
||||
Configure and start OZWDaemon
|
||||
</li>
|
||||
<li>Set up the OpenZWave integration</li>
|
||||
<li>
|
||||
Migrate entities and devices to the new
|
||||
integration
|
||||
</li>
|
||||
<li>Remove legacy Z-Wave integration</li>
|
||||
</ol>
|
||||
<p>
|
||||
<b>
|
||||
Please take a backup of your environment before
|
||||
proceeding.
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._continue}>
|
||||
Continue
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: ``}
|
||||
${this._step === 1
|
||||
? html`
|
||||
<ha-card class="content" header="Stop Z-Wave Network">
|
||||
<div class="card-content">
|
||||
<p>
|
||||
We need to stop the Z-Wave network to perform the
|
||||
migration. Home Assistant will not be able to
|
||||
control Z-Wave devices while the network is stopped.
|
||||
</p>
|
||||
${this._stoppingNetwork
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress
|
||||
active
|
||||
></ha-circular-progress>
|
||||
<div><p>Stopping Z-Wave Network...</p></div>
|
||||
</div>
|
||||
`
|
||||
: ``}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._stopNetwork}>
|
||||
Stop Network
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: ``}
|
||||
${this._step === 2
|
||||
? html`
|
||||
<ha-card class="content" header="Set up OZWDaemon">
|
||||
<div class="card-content">
|
||||
<p>Now it's time to set up the OZW integration.</p>
|
||||
${isComponentLoaded(this.hass, "hassio")
|
||||
? html`
|
||||
<p>
|
||||
The OZWDaemon runs in a Home Assistant addon
|
||||
that will be setup next. Make sure to check
|
||||
the checkbox for the addon.
|
||||
</p>
|
||||
`
|
||||
: html`
|
||||
<p>
|
||||
If you're using Home Assistant Core in Docker
|
||||
or a Python venv, see the
|
||||
<a
|
||||
href="https://github.com/OpenZWave/qt-openzwave/blob/master/README.md"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
OZWDaemon readme
|
||||
</a>
|
||||
for setup instructions.
|
||||
</p>
|
||||
<p>
|
||||
Here's the current Z-Wave configuration.
|
||||
You'll need these values when setting up OZW
|
||||
daemon.
|
||||
</p>
|
||||
${this._migrationConfig
|
||||
? html` <blockquote>
|
||||
USB Path:
|
||||
${this._migrationConfig.usb_path}<br />
|
||||
Network Key:
|
||||
${this._migrationConfig.network_key}
|
||||
</blockquote>`
|
||||
: ``}
|
||||
<p>
|
||||
Once OZWDaemon is installed, running, and
|
||||
connected to the MQTT broker click Continue to
|
||||
set up the OpenZWave integration and migrate
|
||||
your devices and entities.
|
||||
</p>
|
||||
`}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._setupOzw}>
|
||||
Continue
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: ``}
|
||||
${this._step === 3
|
||||
? html`
|
||||
<ha-card
|
||||
class="content"
|
||||
header="Migrate devices and entities"
|
||||
>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
Now it's time to migrate your devices and entities
|
||||
from the legacy Z-Wave integration to the OZW
|
||||
integration, to make sure all your UI and
|
||||
automations keep working.
|
||||
</p>
|
||||
${this._migrationData
|
||||
? html`
|
||||
<p>Below is a list of what will be migrated.</p>
|
||||
${this._migratedZwaveEntities!.length !==
|
||||
this._migrationData.zwave_entity_ids.length
|
||||
? html`<h3 class="warning">
|
||||
Not all entities can be migrated! The
|
||||
following entities will not be migrated
|
||||
and might need manual adjustments to
|
||||
your config:
|
||||
</h3>
|
||||
<ul>
|
||||
${this._migrationData.zwave_entity_ids.map(
|
||||
(entity_id) =>
|
||||
!this._migratedZwaveEntities!.includes(
|
||||
entity_id
|
||||
)
|
||||
? html`<li>
|
||||
${computeStateName(
|
||||
this.hass.states[entity_id]
|
||||
)}
|
||||
(${entity_id})
|
||||
</li>`
|
||||
: ""
|
||||
)}
|
||||
</ul>`
|
||||
: ""}
|
||||
${Object.keys(
|
||||
this._migrationData.migration_device_map
|
||||
).length
|
||||
? html`<h3>Devices that will be migrated:</h3>
|
||||
<ul>
|
||||
${Object.keys(
|
||||
this._migrationData
|
||||
.migration_device_map
|
||||
).map(
|
||||
(device_id) =>
|
||||
html`<li>
|
||||
${this._deviceNameLookup[
|
||||
device_id
|
||||
] || device_id}
|
||||
</li>`
|
||||
)}
|
||||
</ul>`
|
||||
: ""}
|
||||
${Object.keys(
|
||||
this._migrationData.migration_entity_map
|
||||
).length
|
||||
? html`<h3>
|
||||
Entities that will be migrated:
|
||||
</h3>
|
||||
<ul>
|
||||
${Object.keys(
|
||||
this._migrationData
|
||||
.migration_entity_map
|
||||
).map(
|
||||
(entity_id) => html`<li>
|
||||
${computeStateName(
|
||||
this.hass.states[entity_id]
|
||||
)}
|
||||
(${entity_id})
|
||||
</li>`
|
||||
)}
|
||||
</ul>`
|
||||
: ""}
|
||||
`
|
||||
: html` <div class="flex-container">
|
||||
<p>Loading migration data...</p>
|
||||
<ha-circular-progress active>
|
||||
</ha-circular-progress>
|
||||
</div>`}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._doMigrate}>
|
||||
Migrate
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: ``}
|
||||
${this._step === 4
|
||||
? html`<ha-card class="content" header="Done!">
|
||||
<div class="card-content">
|
||||
That was all! You are now migrated to the new OZW
|
||||
integration, check if all your devices and entities are
|
||||
back the way they where, if not all entities could be
|
||||
migrated you might have to change those manually.
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._navigateOzw}>
|
||||
Go to OZW config panel
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>`
|
||||
: ""}
|
||||
`}
|
||||
<div class="card-actions">
|
||||
<a
|
||||
href=${`/config/zwave_js?config_entry=${this._zwaveJsEntryId}`}
|
||||
>
|
||||
<mwc-button> Go to Z-Wave JS config panel </mwc-button>
|
||||
</a>
|
||||
</div>
|
||||
</ha-card>`
|
||||
: ""}
|
||||
`}
|
||||
</ha-config-section>
|
||||
</hass-subpage>
|
||||
`;
|
||||
@ -367,29 +396,63 @@ export class ZwaveMigration extends LitElement {
|
||||
this.hass!.callService("zwave", "stop_network");
|
||||
}
|
||||
|
||||
private async _setupOzw() {
|
||||
const ozwConfigFlow = await startOzwConfigFlow(this.hass);
|
||||
if (isComponentLoaded(this.hass, "ozw")) {
|
||||
this._getMigrationData();
|
||||
this._step = 3;
|
||||
return;
|
||||
}
|
||||
private async _setupZwaveJs() {
|
||||
const zwaveJsConfigFlow = await startZwaveJsConfigFlow(this.hass);
|
||||
showConfigFlowDialog(this, {
|
||||
continueFlowId: ozwConfigFlow.flow_id,
|
||||
dialogClosedCallback: () => {
|
||||
if (isComponentLoaded(this.hass, "ozw")) {
|
||||
this._getMigrationData();
|
||||
continueFlowId: zwaveJsConfigFlow.flow_id,
|
||||
dialogClosedCallback: (params) => {
|
||||
if (params.entryId) {
|
||||
this._zwaveJsEntryId = params.entryId;
|
||||
this._getZwaveJSNodesStatus();
|
||||
this._step = 3;
|
||||
}
|
||||
},
|
||||
showAdvanced: this.hass.userData?.showAdvanced,
|
||||
});
|
||||
this.hass.loadBackendTranslation("title", "ozw", true);
|
||||
this.hass.loadBackendTranslation("title", "zwave_js", true);
|
||||
}
|
||||
|
||||
private async _getZwaveJSNodesStatus() {
|
||||
if (this._nodeReadySubscriptions?.length) {
|
||||
const unsubs = await Promise.all(this._nodeReadySubscriptions);
|
||||
unsubs.forEach((unsub) => {
|
||||
unsub();
|
||||
});
|
||||
}
|
||||
this._nodeReadySubscriptions = [];
|
||||
const networkStatus = await fetchZwaveJsNetworkStatus(
|
||||
this.hass,
|
||||
this._zwaveJsEntryId!
|
||||
);
|
||||
const nodeStatePromisses = networkStatus.controller.nodes.map((nodeId) =>
|
||||
fetchNodeStatus(this.hass, this._zwaveJsEntryId!, nodeId)
|
||||
);
|
||||
const nodesNotReady = (await Promise.all(nodeStatePromisses)).filter(
|
||||
(node) => !node.ready
|
||||
);
|
||||
this._getMigrationData();
|
||||
if (nodesNotReady.length === 0) {
|
||||
this._waitingOnDevices = [];
|
||||
return;
|
||||
}
|
||||
this._nodeReadySubscriptions = nodesNotReady.map((node) =>
|
||||
subscribeNodeReady(this.hass, this._zwaveJsEntryId!, node.node_id, () => {
|
||||
this._getZwaveJSNodesStatus();
|
||||
})
|
||||
);
|
||||
const deviceReg = await fetchDeviceRegistry(this.hass);
|
||||
this._waitingOnDevices = deviceReg
|
||||
.map((device) => getIdentifiersFromDevice(device))
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
private async _getMigrationData() {
|
||||
try {
|
||||
this._migrationData = await migrateZwave(this.hass, true);
|
||||
this._migrationData = await migrateZwave(
|
||||
this.hass,
|
||||
this._zwaveJsEntryId!,
|
||||
true
|
||||
);
|
||||
} catch (err) {
|
||||
showAlertDialog(this, {
|
||||
title: "Failed to get migration data!",
|
||||
@ -430,7 +493,7 @@ export class ZwaveMigration extends LitElement {
|
||||
}
|
||||
|
||||
private async _doMigrate() {
|
||||
const data = await migrateZwave(this.hass, false);
|
||||
const data = await migrateZwave(this.hass, this._zwaveJsEntryId!, false);
|
||||
if (!data.migrated) {
|
||||
showAlertDialog(this, { title: "Migration failed!" });
|
||||
return;
|
||||
@ -438,10 +501,6 @@ export class ZwaveMigration extends LitElement {
|
||||
this._step = 4;
|
||||
}
|
||||
|
||||
private _navigateOzw() {
|
||||
navigate("/config/ozw");
|
||||
}
|
||||
|
||||
private _networkStopped(): void {
|
||||
this._unsubscribe();
|
||||
this._getMigrationConfig();
|
||||
|
@ -2667,9 +2667,9 @@
|
||||
"wakeup_interval": "Wake-up Interval"
|
||||
},
|
||||
"migration": {
|
||||
"ozw": {
|
||||
"header": "Migrate to OpenZWave",
|
||||
"introduction": "This wizard will help you migrate from the legacy Z-Wave integration to the OpenZWave integration that is currently in beta."
|
||||
"zwave_js": {
|
||||
"header": "Migrate to Z-Wave JS",
|
||||
"introduction": "This integration is no longer maintained, and we advise you to move to the new Z-Wave JS integration. This wizard will help you migrate from the legacy Z-Wave integration to the new Z-Wave JS integration."
|
||||
}
|
||||
},
|
||||
"network_management": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user