mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Make proper Z-Wave reconfigure flow (#143549)
* Make proper Z-Wave reconfigure flow * Improve backup_failed string
This commit is contained in:
parent
ff2c901930
commit
7c584ece23
@ -2,7 +2,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
import logging
|
||||
@ -26,12 +25,9 @@ from homeassistant.components.hassio import (
|
||||
)
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_USB,
|
||||
ConfigEntry,
|
||||
ConfigEntryBaseFlow,
|
||||
ConfigEntryState,
|
||||
ConfigFlow,
|
||||
ConfigFlowResult,
|
||||
OptionsFlow,
|
||||
)
|
||||
from homeassistant.const import CONF_NAME, CONF_URL
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
@ -177,8 +173,12 @@ async def async_get_usb_ports(hass: HomeAssistant) -> dict[str, str]:
|
||||
return await hass.async_add_executor_job(get_usb_ports)
|
||||
|
||||
|
||||
class BaseZwaveJSFlow(ConfigEntryBaseFlow, ABC):
|
||||
"""Represent the base config flow for Z-Wave JS."""
|
||||
class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Z-Wave JS."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
_title: str
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Set up flow instance."""
|
||||
@ -196,6 +196,15 @@ class BaseZwaveJSFlow(ConfigEntryBaseFlow, ABC):
|
||||
self.install_task: asyncio.Task | None = None
|
||||
self.start_task: asyncio.Task | None = None
|
||||
self.version_info: VersionInfo | None = None
|
||||
self.original_addon_config: dict[str, Any] | None = None
|
||||
self.revert_reason: str | None = None
|
||||
self.backup_task: asyncio.Task | None = None
|
||||
self.restore_backup_task: asyncio.Task | None = None
|
||||
self.backup_data: bytes | None = None
|
||||
self.backup_filepath: str | None = None
|
||||
self.use_addon = False
|
||||
self._reconfiguring = False
|
||||
self._usb_discovery = False
|
||||
|
||||
async def async_step_install_addon(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
@ -257,6 +266,8 @@ class BaseZwaveJSFlow(ConfigEntryBaseFlow, ABC):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Add-on start failed."""
|
||||
if self._reconfiguring:
|
||||
return await self.async_step_start_failed_reconfigure()
|
||||
return self.async_abort(reason="addon_start_failed")
|
||||
|
||||
async def _async_start_addon(self) -> None:
|
||||
@ -290,13 +301,14 @@ class BaseZwaveJSFlow(ConfigEntryBaseFlow, ABC):
|
||||
else:
|
||||
raise CannotConnect("Failed to start Z-Wave JS add-on: timeout")
|
||||
|
||||
@abstractmethod
|
||||
async def async_step_configure_addon(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Ask for config for Z-Wave JS add-on."""
|
||||
if self._reconfiguring:
|
||||
return await self.async_step_configure_addon_reconfigure(user_input)
|
||||
return await self.async_step_configure_addon_user(user_input)
|
||||
|
||||
@abstractmethod
|
||||
async def async_step_finish_addon_setup(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@ -305,6 +317,9 @@ class BaseZwaveJSFlow(ConfigEntryBaseFlow, ABC):
|
||||
Get add-on discovery info and server version info.
|
||||
Set unique id and abort if already configured.
|
||||
"""
|
||||
if self._reconfiguring:
|
||||
return await self.async_step_finish_addon_setup_reconfigure(user_input)
|
||||
return await self.async_step_finish_addon_setup_user(user_input)
|
||||
|
||||
async def _async_get_addon_info(self) -> AddonInfo:
|
||||
"""Return and cache Z-Wave JS add-on info."""
|
||||
@ -342,28 +357,6 @@ class BaseZwaveJSFlow(ConfigEntryBaseFlow, ABC):
|
||||
|
||||
return discovery_info_config
|
||||
|
||||
|
||||
class ZWaveJSConfigFlow(BaseZwaveJSFlow, ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Z-Wave JS."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
_title: str
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Set up flow instance."""
|
||||
super().__init__()
|
||||
self.use_addon = False
|
||||
self._usb_discovery = False
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(
|
||||
config_entry: ConfigEntry,
|
||||
) -> OptionsFlowHandler:
|
||||
"""Return the options flow."""
|
||||
return OptionsFlowHandler()
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@ -373,6 +366,19 @@ class ZWaveJSConfigFlow(BaseZwaveJSFlow, ConfigFlow, domain=DOMAIN):
|
||||
|
||||
return await self.async_step_manual()
|
||||
|
||||
async def async_step_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Confirm if we are migrating adapters or just re-configuring."""
|
||||
self._reconfiguring = True
|
||||
return self.async_show_menu(
|
||||
step_id="reconfigure",
|
||||
menu_options=[
|
||||
OPTIONS_INTENT_RECONFIGURE,
|
||||
OPTIONS_INTENT_MIGRATE,
|
||||
],
|
||||
)
|
||||
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: ZeroconfServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
@ -568,14 +574,14 @@ class ZWaveJSConfigFlow(BaseZwaveJSFlow, ConfigFlow, domain=DOMAIN):
|
||||
self.lr_s2_authenticated_key = addon_config.get(
|
||||
CONF_ADDON_LR_S2_AUTHENTICATED_KEY, ""
|
||||
)
|
||||
return await self.async_step_finish_addon_setup()
|
||||
return await self.async_step_finish_addon_setup_user()
|
||||
|
||||
if addon_info.state == AddonState.NOT_RUNNING:
|
||||
return await self.async_step_configure_addon()
|
||||
return await self.async_step_configure_addon_user()
|
||||
|
||||
return await self.async_step_install_addon()
|
||||
|
||||
async def async_step_configure_addon(
|
||||
async def async_step_configure_addon_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Ask for config for Z-Wave JS add-on."""
|
||||
@ -661,7 +667,7 @@ class ZWaveJSConfigFlow(BaseZwaveJSFlow, ConfigFlow, domain=DOMAIN):
|
||||
|
||||
return self.async_show_form(step_id="configure_addon", data_schema=data_schema)
|
||||
|
||||
async def async_step_finish_addon_setup(
|
||||
async def async_step_finish_addon_setup_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Prepare info needed to complete the config entry.
|
||||
@ -723,35 +729,11 @@ class ZWaveJSConfigFlow(BaseZwaveJSFlow, ConfigFlow, domain=DOMAIN):
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
"""Handle an options flow for Z-Wave JS."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Set up the options flow."""
|
||||
super().__init__()
|
||||
self.original_addon_config: dict[str, Any] | None = None
|
||||
self.revert_reason: str | None = None
|
||||
self.backup_task: asyncio.Task | None = None
|
||||
self.restore_backup_task: asyncio.Task | None = None
|
||||
self.backup_data: bytes | None = None
|
||||
self.backup_filepath: str | None = None
|
||||
|
||||
@callback
|
||||
def _async_update_entry(self, data: dict[str, Any]) -> None:
|
||||
"""Update the config entry with new data."""
|
||||
self.hass.config_entries.async_update_entry(self.config_entry, data=data)
|
||||
|
||||
async def async_step_init(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Confirm if we are migrating adapters or just re-configuring."""
|
||||
return self.async_show_menu(
|
||||
step_id="init",
|
||||
menu_options=[
|
||||
OPTIONS_INTENT_RECONFIGURE,
|
||||
OPTIONS_INTENT_MIGRATE,
|
||||
],
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self._get_reconfigure_entry(), data=data
|
||||
)
|
||||
|
||||
async def async_step_intent_reconfigure(
|
||||
@ -759,15 +741,15 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
) -> ConfigFlowResult:
|
||||
"""Manage the options."""
|
||||
if is_hassio(self.hass):
|
||||
return await self.async_step_on_supervisor()
|
||||
return await self.async_step_on_supervisor_reconfigure()
|
||||
|
||||
return await self.async_step_manual()
|
||||
return await self.async_step_manual_reconfigure()
|
||||
|
||||
async def async_step_intent_migrate(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Confirm the user wants to reset their current controller."""
|
||||
if not self.config_entry.data.get(CONF_USE_ADDON):
|
||||
if not self._get_reconfigure_entry().data.get(CONF_USE_ADDON):
|
||||
return self.async_abort(reason="addon_required")
|
||||
|
||||
if user_input is not None:
|
||||
@ -837,7 +819,7 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
# reset the old controller
|
||||
try:
|
||||
await self._get_driver().async_hard_reset()
|
||||
except FailedCommand as err:
|
||||
except (AbortFlow, FailedCommand) as err:
|
||||
_LOGGER.error("Failed to reset controller: %s", err)
|
||||
return self.async_abort(reason="reset_failed")
|
||||
|
||||
@ -848,16 +830,15 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
},
|
||||
)
|
||||
|
||||
async def async_step_manual(
|
||||
async def async_step_manual_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a manual configuration."""
|
||||
config_entry = self._get_reconfigure_entry()
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
step_id="manual",
|
||||
data_schema=get_manual_schema(
|
||||
{CONF_URL: self.config_entry.data[CONF_URL]}
|
||||
),
|
||||
step_id="manual_reconfigure",
|
||||
data_schema=get_manual_schema({CONF_URL: config_entry.data[CONF_URL]}),
|
||||
)
|
||||
|
||||
errors = {}
|
||||
@ -870,43 +851,46 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
else:
|
||||
if self.config_entry.unique_id != str(version_info.home_id):
|
||||
if config_entry.unique_id != str(version_info.home_id):
|
||||
return self.async_abort(reason="different_device")
|
||||
|
||||
# Make sure we disable any add-on handling
|
||||
# if the controller is reconfigured in a manual step.
|
||||
self._async_update_entry(
|
||||
{
|
||||
**self.config_entry.data,
|
||||
**config_entry.data,
|
||||
**user_input,
|
||||
CONF_USE_ADDON: False,
|
||||
CONF_INTEGRATION_CREATED_ADDON: False,
|
||||
}
|
||||
)
|
||||
|
||||
self.hass.config_entries.async_schedule_reload(self.config_entry.entry_id)
|
||||
return self.async_create_entry(title=TITLE, data={})
|
||||
self.hass.config_entries.async_schedule_reload(config_entry.entry_id)
|
||||
return self.async_abort(reason="reconfigure_successful")
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="manual", data_schema=get_manual_schema(user_input), errors=errors
|
||||
step_id="manual_reconfigure",
|
||||
data_schema=get_manual_schema(user_input),
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def async_step_on_supervisor(
|
||||
async def async_step_on_supervisor_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle logic when on Supervisor host."""
|
||||
config_entry = self._get_reconfigure_entry()
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
step_id="on_supervisor",
|
||||
step_id="on_supervisor_reconfigure",
|
||||
data_schema=get_on_supervisor_schema(
|
||||
{CONF_USE_ADDON: self.config_entry.data.get(CONF_USE_ADDON, True)}
|
||||
{CONF_USE_ADDON: config_entry.data.get(CONF_USE_ADDON, True)}
|
||||
),
|
||||
)
|
||||
|
||||
if not user_input[CONF_USE_ADDON]:
|
||||
if self.config_entry.data.get(CONF_USE_ADDON):
|
||||
if config_entry.data.get(CONF_USE_ADDON):
|
||||
# Unload the config entry before stopping the add-on.
|
||||
await self.hass.config_entries.async_unload(self.config_entry.entry_id)
|
||||
await self.hass.config_entries.async_unload(config_entry.entry_id)
|
||||
addon_manager = get_addon_manager(self.hass)
|
||||
_LOGGER.debug("Stopping Z-Wave JS add-on")
|
||||
try:
|
||||
@ -914,22 +898,23 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
except AddonError as err:
|
||||
_LOGGER.error(err)
|
||||
self.hass.config_entries.async_schedule_reload(
|
||||
self.config_entry.entry_id
|
||||
config_entry.entry_id
|
||||
)
|
||||
raise AbortFlow("addon_stop_failed") from err
|
||||
return await self.async_step_manual()
|
||||
return await self.async_step_manual_reconfigure()
|
||||
|
||||
addon_info = await self._async_get_addon_info()
|
||||
|
||||
if addon_info.state == AddonState.NOT_INSTALLED:
|
||||
return await self.async_step_install_addon()
|
||||
|
||||
return await self.async_step_configure_addon()
|
||||
return await self.async_step_configure_addon_reconfigure()
|
||||
|
||||
async def async_step_configure_addon(
|
||||
async def async_step_configure_addon_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Ask for config for Z-Wave JS add-on."""
|
||||
config_entry = self._get_reconfigure_entry()
|
||||
addon_info = await self._async_get_addon_info()
|
||||
addon_config = addon_info.options
|
||||
|
||||
@ -967,11 +952,11 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
await self._async_set_addon_config(new_addon_config)
|
||||
|
||||
if addon_info.state == AddonState.RUNNING and not self.restart_addon:
|
||||
return await self.async_step_finish_addon_setup()
|
||||
return await self.async_step_finish_addon_setup_reconfigure()
|
||||
|
||||
if self.config_entry.data.get(CONF_USE_ADDON):
|
||||
if config_entry.data.get(CONF_USE_ADDON):
|
||||
# Disconnect integration before restarting add-on.
|
||||
await self.hass.config_entries.async_unload(self.config_entry.entry_id)
|
||||
await self.hass.config_entries.async_unload(config_entry.entry_id)
|
||||
|
||||
return await self.async_step_start_addon()
|
||||
|
||||
@ -1065,7 +1050,7 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
step_id="choose_serial_port", data_schema=data_schema
|
||||
)
|
||||
|
||||
async def async_step_start_failed(
|
||||
async def async_step_start_failed_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Add-on start failed."""
|
||||
@ -1087,9 +1072,9 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Migration done."""
|
||||
return self.async_create_entry(title=TITLE, data={})
|
||||
return self.async_abort(reason="migration_successful")
|
||||
|
||||
async def async_step_finish_addon_setup(
|
||||
async def async_step_finish_addon_setup_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Prepare info needed to complete the config entry update.
|
||||
@ -1097,6 +1082,7 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
Get add-on discovery info and server version info.
|
||||
Check for same unique id and abort if not the same unique id.
|
||||
"""
|
||||
config_entry = self._get_reconfigure_entry()
|
||||
if self.revert_reason:
|
||||
self.original_addon_config = None
|
||||
reason = self.revert_reason
|
||||
@ -1115,14 +1101,14 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
except CannotConnect:
|
||||
return await self.async_revert_addon_config(reason="cannot_connect")
|
||||
|
||||
if self.backup_data is None and self.config_entry.unique_id != str(
|
||||
if self.backup_data is None and config_entry.unique_id != str(
|
||||
self.version_info.home_id
|
||||
):
|
||||
return await self.async_revert_addon_config(reason="different_device")
|
||||
|
||||
self._async_update_entry(
|
||||
{
|
||||
**self.config_entry.data,
|
||||
**config_entry.data,
|
||||
# this will only be different in a migration flow
|
||||
"unique_id": str(self.version_info.home_id),
|
||||
CONF_URL: self.ws_address,
|
||||
@ -1141,8 +1127,8 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
return await self.async_step_restore_nvm()
|
||||
|
||||
# Always reload entry since we may have disconnected the client.
|
||||
self.hass.config_entries.async_schedule_reload(self.config_entry.entry_id)
|
||||
return self.async_create_entry(title=TITLE, data={})
|
||||
self.hass.config_entries.async_schedule_reload(config_entry.entry_id)
|
||||
return self.async_abort(reason="reconfigure_successful")
|
||||
|
||||
async def async_revert_addon_config(self, reason: str) -> ConfigFlowResult:
|
||||
"""Abort the options flow.
|
||||
@ -1157,7 +1143,9 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
)
|
||||
|
||||
if self.revert_reason or not self.original_addon_config:
|
||||
self.hass.config_entries.async_schedule_reload(self.config_entry.entry_id)
|
||||
self.hass.config_entries.async_schedule_reload(
|
||||
self._get_reconfigure_entry().entry_id
|
||||
)
|
||||
return self.async_abort(reason=reason)
|
||||
|
||||
self.revert_reason = reason
|
||||
@ -1167,7 +1155,7 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
if addon_key in ADDON_USER_INPUT_MAP
|
||||
}
|
||||
_LOGGER.debug("Reverting add-on options, reason: %s", reason)
|
||||
return await self.async_step_configure_addon(addon_config_input)
|
||||
return await self.async_step_configure_addon_reconfigure(addon_config_input)
|
||||
|
||||
async def _async_backup_network(self) -> None:
|
||||
"""Backup the current network."""
|
||||
@ -1203,7 +1191,9 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
assert self.backup_data is not None
|
||||
|
||||
# Reload the config entry to reconnect the client after the addon restart
|
||||
await self.hass.config_entries.async_reload(self.config_entry.entry_id)
|
||||
await self.hass.config_entries.async_reload(
|
||||
self._get_reconfigure_entry().entry_id
|
||||
)
|
||||
|
||||
@callback
|
||||
def forward_progress(event: dict) -> None:
|
||||
@ -1231,9 +1221,11 @@ class OptionsFlowHandler(BaseZwaveJSFlow, OptionsFlow):
|
||||
unsub()
|
||||
|
||||
def _get_driver(self) -> Driver:
|
||||
if self.config_entry.state != ConfigEntryState.LOADED:
|
||||
"""Get the driver from the config entry."""
|
||||
config_entry = self._get_reconfigure_entry()
|
||||
if config_entry.state != ConfigEntryState.LOADED:
|
||||
raise AbortFlow("Configuration entry is not loaded")
|
||||
client: Client = self.config_entry.runtime_data[DATA_CLIENT]
|
||||
client: Client = config_entry.runtime_data[DATA_CLIENT]
|
||||
assert client.driver is not None
|
||||
return client.driver
|
||||
|
||||
|
@ -4,17 +4,22 @@
|
||||
"addon_get_discovery_info_failed": "Failed to get Z-Wave add-on discovery info.",
|
||||
"addon_info_failed": "Failed to get Z-Wave add-on info.",
|
||||
"addon_install_failed": "Failed to install the Z-Wave add-on.",
|
||||
"addon_required": "The Z-Wave migration flow requires the integration to be configured using the Z-Wave Supervisor add-on. You can still use the Backup and Restore buttons to migrate your network manually.",
|
||||
"addon_set_config_failed": "Failed to set Z-Wave configuration.",
|
||||
"addon_start_failed": "Failed to start the Z-Wave add-on.",
|
||||
"addon_stop_failed": "Failed to stop the Z-Wave add-on.",
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"backup_failed": "Failed to back up network.",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"different_device": "The connected USB device is not the same as previously configured for this config entry. Please instead create a new config entry for the new device.",
|
||||
"discovery_requires_supervisor": "Discovery requires the supervisor.",
|
||||
"migration_successful": "Migration successful.",
|
||||
"not_zwave_device": "Discovered device is not a Z-Wave device.",
|
||||
"not_zwave_js_addon": "Discovered add-on is not the official Z-Wave add-on.",
|
||||
"backup_failed": "Failed to backup network.",
|
||||
"restore_failed": "Failed to restore network.",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||
"reset_failed": "Failed to reset controller.",
|
||||
"restore_failed": "Failed to restore network.",
|
||||
"usb_ports_failed": "Failed to get USB devices."
|
||||
},
|
||||
"error": {
|
||||
@ -42,6 +47,19 @@
|
||||
"description": "The add-on will generate security keys if those fields are left empty.",
|
||||
"title": "Enter the Z-Wave add-on configuration"
|
||||
},
|
||||
"configure_addon_reconfigure": {
|
||||
"data": {
|
||||
"emulate_hardware": "Emulate Hardware",
|
||||
"log_level": "Log level",
|
||||
"s0_legacy_key": "[%key:component::zwave_js::config::step::configure_addon::data::s0_legacy_key%]",
|
||||
"s2_access_control_key": "[%key:component::zwave_js::config::step::configure_addon::data::s2_access_control_key%]",
|
||||
"s2_authenticated_key": "[%key:component::zwave_js::config::step::configure_addon::data::s2_authenticated_key%]",
|
||||
"s2_unauthenticated_key": "[%key:component::zwave_js::config::step::configure_addon::data::s2_unauthenticated_key%]",
|
||||
"usb_path": "[%key:common::config_flow::data::usb_path%]"
|
||||
},
|
||||
"description": "[%key:component::zwave_js::config::step::configure_addon::description%]",
|
||||
"title": "[%key:component::zwave_js::config::step::configure_addon::title%]"
|
||||
},
|
||||
"hassio_confirm": {
|
||||
"title": "Set up Z-Wave integration with the Z-Wave add-on"
|
||||
},
|
||||
@ -53,6 +71,11 @@
|
||||
"url": "[%key:common::config_flow::data::url%]"
|
||||
}
|
||||
},
|
||||
"manual_reconfigure": {
|
||||
"data": {
|
||||
"url": "[%key:common::config_flow::data::url%]"
|
||||
}
|
||||
},
|
||||
"on_supervisor": {
|
||||
"data": {
|
||||
"use_addon": "Use the Z-Wave Supervisor add-on"
|
||||
@ -60,6 +83,13 @@
|
||||
"description": "Do you want to use the Z-Wave Supervisor add-on?",
|
||||
"title": "Select connection method"
|
||||
},
|
||||
"on_supervisor_reconfigure": {
|
||||
"data": {
|
||||
"use_addon": "[%key:component::zwave_js::config::step::on_supervisor::data::use_addon%]"
|
||||
},
|
||||
"description": "[%key:component::zwave_js::config::step::on_supervisor::description%]",
|
||||
"title": "[%key:component::zwave_js::config::step::on_supervisor::title%]"
|
||||
},
|
||||
"start_addon": {
|
||||
"title": "The Z-Wave add-on is starting."
|
||||
},
|
||||
@ -69,6 +99,28 @@
|
||||
"zeroconf_confirm": {
|
||||
"description": "Do you want to add the Z-Wave Server with home ID {home_id} found at {url} to Home Assistant?",
|
||||
"title": "Discovered Z-Wave Server"
|
||||
},
|
||||
"reconfigure": {
|
||||
"title": "Migrate or re-configure",
|
||||
"description": "Are you migrating to a new controller or re-configuring the current controller?",
|
||||
"menu_options": {
|
||||
"intent_migrate": "Migrate to a new controller",
|
||||
"intent_reconfigure": "Re-configure the current controller"
|
||||
}
|
||||
},
|
||||
"intent_migrate": {
|
||||
"title": "[%key:component::zwave_js::config::step::reconfigure::menu_options::intent_migrate%]",
|
||||
"description": "Before setting up your new controller, your old controller needs to be reset. A backup will be performed first.\n\nDo you wish to continue?"
|
||||
},
|
||||
"instruct_unplug": {
|
||||
"title": "Unplug your old controller",
|
||||
"description": "Backup saved to \"{file_path}\"\n\nYour old controller has been reset. If the hardware is no longer needed, you can now unplug it.\n\nPlease make sure your new controller is plugged in before continuing."
|
||||
},
|
||||
"choose_serial_port": {
|
||||
"data": {
|
||||
"usb_path": "[%key:common::config_flow::data::usb_path%]"
|
||||
},
|
||||
"title": "Select your Z-Wave device"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -213,90 +265,6 @@
|
||||
"title": "Newer version of Z-Wave Server needed"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"abort": {
|
||||
"addon_get_discovery_info_failed": "[%key:component::zwave_js::config::abort::addon_get_discovery_info_failed%]",
|
||||
"addon_info_failed": "[%key:component::zwave_js::config::abort::addon_info_failed%]",
|
||||
"addon_install_failed": "[%key:component::zwave_js::config::abort::addon_install_failed%]",
|
||||
"addon_set_config_failed": "[%key:component::zwave_js::config::abort::addon_set_config_failed%]",
|
||||
"addon_start_failed": "[%key:component::zwave_js::config::abort::addon_start_failed%]",
|
||||
"addon_stop_failed": "Failed to stop the Z-Wave add-on.",
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"different_device": "The connected USB device is not the same as previously configured for this config entry. Please instead create a new config entry for the new device.",
|
||||
"addon_required": "The Z-Wave migration flow requires the integration to be configured using the Z-Wave Supervisor add-on. You can still use the Backup and Restore buttons to migrate your network manually.",
|
||||
"backup_failed": "[%key:component::zwave_js::config::abort::backup_failed%]",
|
||||
"restore_failed": "[%key:component::zwave_js::config::abort::restore_failed%]",
|
||||
"reset_failed": "[%key:component::zwave_js::config::abort::reset_failed%]",
|
||||
"usb_ports_failed": "[%key:component::zwave_js::config::abort::usb_ports_failed%]"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_ws_url": "[%key:component::zwave_js::config::error::invalid_ws_url%]",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"progress": {
|
||||
"install_addon": "[%key:component::zwave_js::config::progress::install_addon%]",
|
||||
"start_addon": "[%key:component::zwave_js::config::progress::start_addon%]",
|
||||
"backup_nvm": "[%key:component::zwave_js::config::progress::backup_nvm%]",
|
||||
"restore_nvm": "[%key:component::zwave_js::config::progress::restore_nvm%]"
|
||||
},
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "Migrate or re-configure",
|
||||
"description": "Are you migrating to a new controller or re-configuring the current controller?",
|
||||
"menu_options": {
|
||||
"intent_migrate": "Migrate to a new controller",
|
||||
"intent_reconfigure": "Re-configure the current controller"
|
||||
}
|
||||
},
|
||||
"intent_migrate": {
|
||||
"title": "[%key:component::zwave_js::options::step::init::menu_options::intent_migrate%]",
|
||||
"description": "Before setting up your new controller, your old controller needs to be reset. A backup will be performed first.\n\nDo you wish to continue?"
|
||||
},
|
||||
"instruct_unplug": {
|
||||
"title": "Unplug your old controller",
|
||||
"description": "Backup saved to \"{file_path}\"\n\nYour old controller has been reset. If the hardware is no longer needed, you can now unplug it.\n\nPlease make sure your new controller is plugged in before continuing."
|
||||
},
|
||||
"configure_addon": {
|
||||
"data": {
|
||||
"emulate_hardware": "Emulate Hardware",
|
||||
"log_level": "Log level",
|
||||
"s0_legacy_key": "[%key:component::zwave_js::config::step::configure_addon::data::s0_legacy_key%]",
|
||||
"s2_access_control_key": "[%key:component::zwave_js::config::step::configure_addon::data::s2_access_control_key%]",
|
||||
"s2_authenticated_key": "[%key:component::zwave_js::config::step::configure_addon::data::s2_authenticated_key%]",
|
||||
"s2_unauthenticated_key": "[%key:component::zwave_js::config::step::configure_addon::data::s2_unauthenticated_key%]",
|
||||
"usb_path": "[%key:common::config_flow::data::usb_path%]"
|
||||
},
|
||||
"description": "[%key:component::zwave_js::config::step::configure_addon::description%]",
|
||||
"title": "[%key:component::zwave_js::config::step::configure_addon::title%]"
|
||||
},
|
||||
"choose_serial_port": {
|
||||
"data": {
|
||||
"usb_path": "[%key:common::config_flow::data::usb_path%]"
|
||||
},
|
||||
"title": "Select your Z-Wave device"
|
||||
},
|
||||
"install_addon": {
|
||||
"title": "[%key:component::zwave_js::config::step::install_addon::title%]"
|
||||
},
|
||||
"manual": {
|
||||
"data": {
|
||||
"url": "[%key:common::config_flow::data::url%]"
|
||||
}
|
||||
},
|
||||
"on_supervisor": {
|
||||
"data": {
|
||||
"use_addon": "[%key:component::zwave_js::config::step::on_supervisor::data::use_addon%]"
|
||||
},
|
||||
"description": "[%key:component::zwave_js::config::step::on_supervisor::description%]",
|
||||
"title": "[%key:component::zwave_js::config::step::on_supervisor::title%]"
|
||||
},
|
||||
"start_addon": {
|
||||
"title": "[%key:component::zwave_js::config::step::start_addon::title%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"bulk_set_partial_config_parameters": {
|
||||
"description": "Allows for bulk setting partial parameters. Useful when multiple partial parameters have to be set at the same time.",
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user