mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 02:06:42 +00:00
Zwave -> OZW migration (#7765)
Co-authored-by: Joakim Sørensen <joasoe@gmail.com>
This commit is contained in:
parent
2ce70206c6
commit
9243d300cc
@ -71,7 +71,7 @@ export const updateDeviceRegistryEntry = (
|
|||||||
...updates,
|
...updates,
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchDeviceRegistry = (conn) =>
|
export const fetchDeviceRegistry = (conn) =>
|
||||||
conn.sendMessagePromise({
|
conn.sendMessagePromise({
|
||||||
type: "config/device_registry/list",
|
type: "config/device_registry/list",
|
||||||
});
|
});
|
||||||
|
@ -73,6 +73,14 @@ export interface OZWDeviceConfig {
|
|||||||
help: string;
|
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 = [
|
export const nodeQueryStages = [
|
||||||
"ProtocolInfo",
|
"ProtocolInfo",
|
||||||
"Probe",
|
"Probe",
|
||||||
@ -147,7 +155,7 @@ export const fetchOZWNetworkStatus = (
|
|||||||
): Promise<OZWInstance> =>
|
): Promise<OZWInstance> =>
|
||||||
hass.callWS({
|
hass.callWS({
|
||||||
type: "ozw/network_status",
|
type: "ozw/network_status",
|
||||||
ozw_instance: ozw_instance,
|
ozw_instance,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchOZWNetworkStatistics = (
|
export const fetchOZWNetworkStatistics = (
|
||||||
@ -156,7 +164,7 @@ export const fetchOZWNetworkStatistics = (
|
|||||||
): Promise<OZWNetworkStatistics> =>
|
): Promise<OZWNetworkStatistics> =>
|
||||||
hass.callWS({
|
hass.callWS({
|
||||||
type: "ozw/network_statistics",
|
type: "ozw/network_statistics",
|
||||||
ozw_instance: ozw_instance,
|
ozw_instance,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchOZWNodes = (
|
export const fetchOZWNodes = (
|
||||||
@ -165,7 +173,7 @@ export const fetchOZWNodes = (
|
|||||||
): Promise<OZWDevice[]> =>
|
): Promise<OZWDevice[]> =>
|
||||||
hass.callWS({
|
hass.callWS({
|
||||||
type: "ozw/get_nodes",
|
type: "ozw/get_nodes",
|
||||||
ozw_instance: ozw_instance,
|
ozw_instance,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchOZWNodeStatus = (
|
export const fetchOZWNodeStatus = (
|
||||||
@ -175,8 +183,8 @@ export const fetchOZWNodeStatus = (
|
|||||||
): Promise<OZWDevice> =>
|
): Promise<OZWDevice> =>
|
||||||
hass.callWS({
|
hass.callWS({
|
||||||
type: "ozw/node_status",
|
type: "ozw/node_status",
|
||||||
ozw_instance: ozw_instance,
|
ozw_instance,
|
||||||
node_id: node_id,
|
node_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchOZWNodeMetadata = (
|
export const fetchOZWNodeMetadata = (
|
||||||
@ -186,8 +194,8 @@ export const fetchOZWNodeMetadata = (
|
|||||||
): Promise<OZWDeviceMetaDataResponse> =>
|
): Promise<OZWDeviceMetaDataResponse> =>
|
||||||
hass.callWS({
|
hass.callWS({
|
||||||
type: "ozw/node_metadata",
|
type: "ozw/node_metadata",
|
||||||
ozw_instance: ozw_instance,
|
ozw_instance,
|
||||||
node_id: node_id,
|
node_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchOZWNodeConfig = (
|
export const fetchOZWNodeConfig = (
|
||||||
@ -197,8 +205,8 @@ export const fetchOZWNodeConfig = (
|
|||||||
): Promise<OZWDeviceConfig[]> =>
|
): Promise<OZWDeviceConfig[]> =>
|
||||||
hass.callWS({
|
hass.callWS({
|
||||||
type: "ozw/get_config_parameters",
|
type: "ozw/get_config_parameters",
|
||||||
ozw_instance: ozw_instance,
|
ozw_instance,
|
||||||
node_id: node_id,
|
node_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const refreshNodeInfo = (
|
export const refreshNodeInfo = (
|
||||||
@ -208,6 +216,15 @@ export const refreshNodeInfo = (
|
|||||||
): Promise<OZWDevice> =>
|
): Promise<OZWDevice> =>
|
||||||
hass.callWS({
|
hass.callWS({
|
||||||
type: "ozw/refresh_node_info",
|
type: "ozw/refresh_node_info",
|
||||||
ozw_instance: ozw_instance,
|
ozw_instance,
|
||||||
node_id: node_id,
|
node_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const migrateZwave = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
dry_run = true
|
||||||
|
): Promise<OZWMigrationData> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "ozw/migrate_zwave",
|
||||||
|
dry_run,
|
||||||
});
|
});
|
||||||
|
@ -42,6 +42,11 @@ export interface ZWaveAttributes {
|
|||||||
wake_up_interval?: number;
|
wake_up_interval?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ZWaveMigrationConfig {
|
||||||
|
usb_path: string;
|
||||||
|
network_key: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const ZWAVE_NETWORK_STATE_STOPPED = 0;
|
export const ZWAVE_NETWORK_STATE_STOPPED = 0;
|
||||||
export const ZWAVE_NETWORK_STATE_FAILED = 1;
|
export const ZWAVE_NETWORK_STATE_FAILED = 1;
|
||||||
export const ZWAVE_NETWORK_STATE_STARTED = 5;
|
export const ZWAVE_NETWORK_STATE_STARTED = 5;
|
||||||
@ -55,6 +60,20 @@ export const fetchNetworkStatus = (
|
|||||||
type: "zwave/network_status",
|
type: "zwave/network_status",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const startOzwConfigFlow = (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<{ flow_id: string }> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "zwave/start_ozw_config_flow",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const fetchMigrationConfig = (
|
||||||
|
hass: HomeAssistant
|
||||||
|
): Promise<ZWaveMigrationConfig> =>
|
||||||
|
hass.callWS({
|
||||||
|
type: "zwave/get_migration_config",
|
||||||
|
});
|
||||||
|
|
||||||
export const fetchValues = (hass: HomeAssistant, nodeId: number) =>
|
export const fetchValues = (hass: HomeAssistant, nodeId: number) =>
|
||||||
hass.callApi<ZWaveValue[]>("GET", `zwave/values/${nodeId}`);
|
hass.callApi<ZWaveValue[]>("GET", `zwave/values/${nodeId}`);
|
||||||
|
|
||||||
|
@ -293,9 +293,9 @@ class HaPanelConfig extends HassRouterPage {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
zwave: {
|
zwave: {
|
||||||
tag: "ha-config-zwave",
|
tag: "zwave-config-router",
|
||||||
load: () =>
|
load: () =>
|
||||||
import("./integrations/integration-panels/zwave/ha-config-zwave"),
|
import("./integrations/integration-panels/zwave/zwave-config-router"),
|
||||||
},
|
},
|
||||||
mqtt: {
|
mqtt: {
|
||||||
tag: "mqtt-config-panel",
|
tag: "mqtt-config-panel",
|
||||||
|
@ -102,6 +102,36 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
</app-header>
|
</app-header>
|
||||||
|
|
||||||
|
<ha-config-section is-wide="[[isWide]]">
|
||||||
|
<ha-card
|
||||||
|
class="content"
|
||||||
|
header="[[localize('ui.panel.config.zwave.migration.ozw.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>
|
||||||
|
</div>
|
||||||
|
<div class="card-actions">
|
||||||
|
<a href="/config/zwave/migration"
|
||||||
|
><mwc-button>Start Migration to OZW</mwc-button></a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
</ha-config-section>
|
||||||
|
|
||||||
<zwave-network
|
<zwave-network
|
||||||
id="zwave-network"
|
id="zwave-network"
|
||||||
is-wide="[[isWide]]"
|
is-wide="[[isWide]]"
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
import { customElement, property } from "lit-element";
|
||||||
|
import {
|
||||||
|
HassRouterPage,
|
||||||
|
RouterOptions,
|
||||||
|
} from "../../../../../layouts/hass-router-page";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { navigate } from "../../../../../common/navigate";
|
||||||
|
|
||||||
|
@customElement("zwave-config-router")
|
||||||
|
class ZWaveConfigRouter extends HassRouterPage {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public isWide!: boolean;
|
||||||
|
|
||||||
|
@property() public narrow!: boolean;
|
||||||
|
|
||||||
|
private _configEntry = new URLSearchParams(window.location.search).get(
|
||||||
|
"config_entry"
|
||||||
|
);
|
||||||
|
|
||||||
|
protected routerOptions: RouterOptions = {
|
||||||
|
defaultPage: "dashboard",
|
||||||
|
showLoading: true,
|
||||||
|
routes: {
|
||||||
|
dashboard: {
|
||||||
|
tag: "ha-config-zwave",
|
||||||
|
load: () =>
|
||||||
|
import(/* webpackChunkName: "ha-config-zwave" */ "./ha-config-zwave"),
|
||||||
|
},
|
||||||
|
migration: {
|
||||||
|
tag: "zwave-migration",
|
||||||
|
load: () =>
|
||||||
|
import(/* webpackChunkName: "zwave-migration" */ "./zwave-migration"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
protected updatePageEl(el): void {
|
||||||
|
el.route = this.routeTail;
|
||||||
|
el.hass = this.hass;
|
||||||
|
el.isWide = this.isWide;
|
||||||
|
el.narrow = this.narrow;
|
||||||
|
el.configEntryId = this._configEntry;
|
||||||
|
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
if (this._configEntry && !searchParams.has("config_entry")) {
|
||||||
|
searchParams.append("config_entry", this._configEntry);
|
||||||
|
navigate(
|
||||||
|
this,
|
||||||
|
`${this.routeTail.prefix}${
|
||||||
|
this.routeTail.path
|
||||||
|
}?${searchParams.toString()}`,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"zwave-config-router": ZWaveConfigRouter;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,480 @@
|
|||||||
|
import "@polymer/app-layout/app-header/app-header";
|
||||||
|
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
import "../../../../../components/ha-icon-button";
|
||||||
|
import "../../../../../components/ha-circular-progress";
|
||||||
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
internalProperty,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import "../../../../../components/buttons/ha-call-api-button";
|
||||||
|
import "../../../../../components/buttons/ha-call-service-button";
|
||||||
|
import "../../../../../components/ha-card";
|
||||||
|
import "../../../../../components/ha-icon";
|
||||||
|
import {
|
||||||
|
fetchNetworkStatus,
|
||||||
|
ZWaveNetworkStatus,
|
||||||
|
ZWAVE_NETWORK_STATE_STOPPED,
|
||||||
|
fetchMigrationConfig,
|
||||||
|
ZWaveMigrationConfig,
|
||||||
|
startOzwConfigFlow,
|
||||||
|
} from "../../../../../data/zwave";
|
||||||
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
|
import type { HomeAssistant, Route } from "../../../../../types";
|
||||||
|
import "../../../ha-config-section";
|
||||||
|
import "../../../../../layouts/hass-subpage";
|
||||||
|
import { showConfigFlowDialog } from "../../../../../dialogs/config-flow/show-dialog-config-flow";
|
||||||
|
import { migrateZwave, OZWMigrationData } from "../../../../../data/ozw";
|
||||||
|
import { navigate } from "../../../../../common/navigate";
|
||||||
|
import { showAlertDialog } from "../../../../../dialogs/generic/show-dialog-box";
|
||||||
|
import { computeStateName } from "../../../../../common/entity/compute_state_name";
|
||||||
|
import {
|
||||||
|
computeDeviceName,
|
||||||
|
DeviceRegistryEntry,
|
||||||
|
fetchDeviceRegistry,
|
||||||
|
} from "../../../../../data/device_registry";
|
||||||
|
|
||||||
|
@customElement("zwave-migration")
|
||||||
|
export class ZwaveMigration extends LitElement {
|
||||||
|
@property({ type: Object }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ type: Object }) public route!: Route;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public narrow!: boolean;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public isWide!: boolean;
|
||||||
|
|
||||||
|
@internalProperty() private _networkStatus?: ZWaveNetworkStatus;
|
||||||
|
|
||||||
|
@internalProperty() private _unsub?: Promise<UnsubscribeFunc>;
|
||||||
|
|
||||||
|
@internalProperty() private _step = 0;
|
||||||
|
|
||||||
|
@internalProperty() private _stoppingNetwork = false;
|
||||||
|
|
||||||
|
@internalProperty() private _migrationConfig?: ZWaveMigrationConfig;
|
||||||
|
|
||||||
|
@internalProperty() private _migrationData?: OZWMigrationData;
|
||||||
|
|
||||||
|
@internalProperty() private _migratedZwaveEntities?: string[];
|
||||||
|
|
||||||
|
@internalProperty() private _deviceRegistry?: DeviceRegistryEntry[];
|
||||||
|
|
||||||
|
public disconnectedCallback(): void {
|
||||||
|
this._unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<hass-subpage
|
||||||
|
.hass=${this.hass}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
.route=${this.route}
|
||||||
|
back-path="/config/zwave"
|
||||||
|
>
|
||||||
|
<ha-config-section .narrow=${this.narrow} .isWide=${this.isWide}>
|
||||||
|
<div slot="header">
|
||||||
|
${this.hass.localize("ui.panel.config.zwave.migration.ozw.header")}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="introduction">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave.migration.ozw.introduction"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
${!this.hass.config.components.includes("mqtt")
|
||||||
|
? html`
|
||||||
|
<ha-card class="content" header="MQTT Required">
|
||||||
|
<div class="card-content">
|
||||||
|
<p>
|
||||||
|
OpenZWave requires MQTT. Please setup an MQTT broker and
|
||||||
|
the MQTT integration to proceed with the migration.
|
||||||
|
</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 or a snapshot 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>
|
||||||
|
${this.hass.config.components.includes("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._computeDeviceName(
|
||||||
|
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>`
|
||||||
|
: ""}
|
||||||
|
`}
|
||||||
|
</ha-config-section>
|
||||||
|
</hass-subpage>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _getMigrationConfig(): Promise<void> {
|
||||||
|
this._migrationConfig = await fetchMigrationConfig(this.hass!);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _unsubscribe(): Promise<void> {
|
||||||
|
if (this._unsub) {
|
||||||
|
(await this._unsub)();
|
||||||
|
this._unsub = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _continue(): void {
|
||||||
|
this._step++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _stopNetwork(): Promise<void> {
|
||||||
|
this._stoppingNetwork = true;
|
||||||
|
await this._getNetworkStatus();
|
||||||
|
if (this._networkStatus?.state === ZWAVE_NETWORK_STATE_STOPPED) {
|
||||||
|
this._networkStopped();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._unsub = this.hass!.connection.subscribeEvents(
|
||||||
|
() => this._networkStopped(),
|
||||||
|
"zwave.network_stop"
|
||||||
|
);
|
||||||
|
this.hass!.callService("zwave", "stop_network");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _setupOzw() {
|
||||||
|
const ozwConfigFlow = await startOzwConfigFlow(this.hass);
|
||||||
|
if (
|
||||||
|
!this.hass.config.components.includes("hassio") &&
|
||||||
|
this.hass.config.components.includes("ozw")
|
||||||
|
) {
|
||||||
|
this._getMigrationData();
|
||||||
|
this._step = 3;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showConfigFlowDialog(this, {
|
||||||
|
continueFlowId: ozwConfigFlow.flow_id,
|
||||||
|
dialogClosedCallback: () => {
|
||||||
|
if (this.hass.config.components.includes("ozw")) {
|
||||||
|
this._getMigrationData();
|
||||||
|
this._step = 3;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showAdvanced: this.hass.userData?.showAdvanced,
|
||||||
|
});
|
||||||
|
this.hass.loadBackendTranslation("title", "ozw", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _getMigrationData() {
|
||||||
|
this._migrationData = await migrateZwave(this.hass, true);
|
||||||
|
this._migratedZwaveEntities = Object.keys(
|
||||||
|
this._migrationData.migration_entity_map
|
||||||
|
);
|
||||||
|
if (Object.keys(this._migrationData.migration_device_map).length) {
|
||||||
|
this._deviceRegistry = await fetchDeviceRegistry(this.hass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _computeDeviceName(deviceId) {
|
||||||
|
const device = this._deviceRegistry?.find(
|
||||||
|
(devReg) => devReg.id === deviceId
|
||||||
|
);
|
||||||
|
if (!device) {
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
return computeDeviceName(device, this.hass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _doMigrate() {
|
||||||
|
const data = await migrateZwave(this.hass, false);
|
||||||
|
if (!data.migrated) {
|
||||||
|
showAlertDialog(this, { title: "Migration failed!" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._step = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _navigateOzw() {
|
||||||
|
navigate(this, "/config/ozw");
|
||||||
|
}
|
||||||
|
|
||||||
|
private _networkStopped(): void {
|
||||||
|
this._unsubscribe();
|
||||||
|
this._getMigrationConfig();
|
||||||
|
this._stoppingNetwork = false;
|
||||||
|
this._step = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _getNetworkStatus(): Promise<void> {
|
||||||
|
this._networkStatus = await fetchNetworkStatus(this.hass!);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
.content {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container ha-circular-progress {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
display: block;
|
||||||
|
background-color: var(--secondary-background-color);
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
padding: 8px;
|
||||||
|
margin: 8px 0;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-card {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"zwave-migration": ZwaveMigration;
|
||||||
|
}
|
||||||
|
}
|
@ -2335,6 +2335,12 @@
|
|||||||
"unknown": "unknown",
|
"unknown": "unknown",
|
||||||
"wakeup_interval": "Wakeup Interval"
|
"wakeup_interval": "Wakeup 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."
|
||||||
|
}
|
||||||
|
},
|
||||||
"network_management": {
|
"network_management": {
|
||||||
"header": "Z-Wave Network Management",
|
"header": "Z-Wave Network Management",
|
||||||
"introduction": "Run commands that affect the Z-Wave network. You won't get feedback on whether most commands succeeded, but you can check the OZW Log to try to find out."
|
"introduction": "Run commands that affect the Z-Wave network. You won't get feedback on whether most commands succeeded, but you can check the OZW Log to try to find out."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user