mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 12:47:08 +00:00
Z-WaveJS config flow: Change keys question (#147518)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
This commit is contained in:
parent
41b9a7a9a3
commit
1829acd0e1
@ -40,7 +40,6 @@ from homeassistant.helpers.hassio import is_hassio
|
||||
from homeassistant.helpers.service_info.hassio import HassioServiceInfo
|
||||
from homeassistant.helpers.service_info.usb import UsbServiceInfo
|
||||
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
||||
from homeassistant.helpers.typing import VolDictType
|
||||
|
||||
from .addon import get_addon_manager
|
||||
from .const import (
|
||||
@ -90,6 +89,9 @@ ADDON_USER_INPUT_MAP = {
|
||||
ON_SUPERVISOR_SCHEMA = vol.Schema({vol.Optional(CONF_USE_ADDON, default=True): bool})
|
||||
MIN_MIGRATION_SDK_VERSION = AwesomeVersion("6.61")
|
||||
|
||||
NETWORK_TYPE_NEW = "new"
|
||||
NETWORK_TYPE_EXISTING = "existing"
|
||||
|
||||
|
||||
def get_manual_schema(user_input: dict[str, Any]) -> vol.Schema:
|
||||
"""Return a schema for the manual step."""
|
||||
@ -632,6 +634,81 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Ask for config for Z-Wave JS add-on."""
|
||||
|
||||
if user_input is not None:
|
||||
self.usb_path = user_input[CONF_USB_PATH]
|
||||
return await self.async_step_network_type()
|
||||
|
||||
if self._usb_discovery:
|
||||
return await self.async_step_network_type()
|
||||
|
||||
usb_path = self.usb_path or ""
|
||||
|
||||
try:
|
||||
ports = await async_get_usb_ports(self.hass)
|
||||
except OSError as err:
|
||||
_LOGGER.error("Failed to get USB ports: %s", err)
|
||||
return self.async_abort(reason="usb_ports_failed")
|
||||
|
||||
data_schema = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_USB_PATH, default=usb_path): vol.In(ports),
|
||||
}
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="configure_addon_user", data_schema=data_schema
|
||||
)
|
||||
|
||||
async def async_step_network_type(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Ask for network type (new or existing)."""
|
||||
# For recommended installation, automatically set network type to "new"
|
||||
if self._recommended_install:
|
||||
user_input = {"network_type": NETWORK_TYPE_NEW}
|
||||
|
||||
if user_input is not None:
|
||||
if user_input["network_type"] == NETWORK_TYPE_NEW:
|
||||
# Set all keys to empty strings for new network
|
||||
self.s0_legacy_key = ""
|
||||
self.s2_access_control_key = ""
|
||||
self.s2_authenticated_key = ""
|
||||
self.s2_unauthenticated_key = ""
|
||||
self.lr_s2_access_control_key = ""
|
||||
self.lr_s2_authenticated_key = ""
|
||||
|
||||
addon_config_updates = {
|
||||
CONF_ADDON_DEVICE: self.usb_path,
|
||||
CONF_ADDON_S0_LEGACY_KEY: self.s0_legacy_key,
|
||||
CONF_ADDON_S2_ACCESS_CONTROL_KEY: self.s2_access_control_key,
|
||||
CONF_ADDON_S2_AUTHENTICATED_KEY: self.s2_authenticated_key,
|
||||
CONF_ADDON_S2_UNAUTHENTICATED_KEY: self.s2_unauthenticated_key,
|
||||
CONF_ADDON_LR_S2_ACCESS_CONTROL_KEY: self.lr_s2_access_control_key,
|
||||
CONF_ADDON_LR_S2_AUTHENTICATED_KEY: self.lr_s2_authenticated_key,
|
||||
}
|
||||
|
||||
await self._async_set_addon_config(addon_config_updates)
|
||||
return await self.async_step_start_addon()
|
||||
|
||||
# Network already exists, go to security keys step
|
||||
return await self.async_step_configure_security_keys()
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="network_type",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Required("network_type", default=""): vol.In(
|
||||
[NETWORK_TYPE_NEW, NETWORK_TYPE_EXISTING]
|
||||
)
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
async def async_step_configure_security_keys(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Ask for security keys for existing Z-Wave network."""
|
||||
addon_info = await self._async_get_addon_info()
|
||||
addon_config = addon_info.options
|
||||
|
||||
@ -654,10 +731,6 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
CONF_ADDON_LR_S2_AUTHENTICATED_KEY, self.lr_s2_authenticated_key or ""
|
||||
)
|
||||
|
||||
if self._recommended_install and self._usb_discovery:
|
||||
# Recommended installation with USB discovery, skip asking for keys
|
||||
user_input = {}
|
||||
|
||||
if user_input is not None:
|
||||
self.s0_legacy_key = user_input.get(CONF_S0_LEGACY_KEY, s0_legacy_key)
|
||||
self.s2_access_control_key = user_input.get(
|
||||
@ -675,8 +748,6 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self.lr_s2_authenticated_key = user_input.get(
|
||||
CONF_LR_S2_AUTHENTICATED_KEY, lr_s2_authenticated_key
|
||||
)
|
||||
if not self._usb_discovery:
|
||||
self.usb_path = user_input[CONF_USB_PATH]
|
||||
|
||||
addon_config_updates = {
|
||||
CONF_ADDON_DEVICE: self.usb_path,
|
||||
@ -689,14 +760,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
}
|
||||
|
||||
await self._async_set_addon_config(addon_config_updates)
|
||||
|
||||
return await self.async_step_start_addon()
|
||||
|
||||
usb_path = self.usb_path or addon_config.get(CONF_ADDON_DEVICE) or ""
|
||||
schema: VolDictType = (
|
||||
{}
|
||||
if self._recommended_install
|
||||
else {
|
||||
data_schema = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_S0_LEGACY_KEY, default=s0_legacy_key): str,
|
||||
vol.Optional(
|
||||
CONF_S2_ACCESS_CONTROL_KEY, default=s2_access_control_key
|
||||
@ -716,22 +783,8 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
}
|
||||
)
|
||||
|
||||
if not self._usb_discovery:
|
||||
try:
|
||||
ports = await async_get_usb_ports(self.hass)
|
||||
except OSError as err:
|
||||
_LOGGER.error("Failed to get USB ports: %s", err)
|
||||
return self.async_abort(reason="usb_ports_failed")
|
||||
|
||||
schema = {
|
||||
vol.Required(CONF_USB_PATH, default=usb_path): vol.In(ports),
|
||||
**schema,
|
||||
}
|
||||
|
||||
data_schema = vol.Schema(schema)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="configure_addon_user", data_schema=data_schema
|
||||
step_id="configure_security_keys", data_schema=data_schema
|
||||
)
|
||||
|
||||
async def async_step_finish_addon_setup_user(
|
||||
|
@ -39,25 +39,37 @@
|
||||
"step": {
|
||||
"configure_addon_user": {
|
||||
"data": {
|
||||
"lr_s2_access_control_key": "Long Range S2 Access Control Key",
|
||||
"lr_s2_authenticated_key": "Long Range S2 Authenticated Key",
|
||||
"s0_legacy_key": "S0 Key (Legacy)",
|
||||
"s2_access_control_key": "S2 Access Control Key",
|
||||
"s2_authenticated_key": "S2 Authenticated Key",
|
||||
"s2_unauthenticated_key": "S2 Unauthenticated Key",
|
||||
"usb_path": "[%key:common::config_flow::data::usb_path%]"
|
||||
},
|
||||
"description": "Select your Z-Wave adapter",
|
||||
"title": "Enter the Z-Wave add-on configuration"
|
||||
},
|
||||
"network_type": {
|
||||
"data": {
|
||||
"network_type": "Is your network new or does it already exist?"
|
||||
},
|
||||
"title": "Z-Wave network"
|
||||
},
|
||||
"configure_security_keys": {
|
||||
"data": {
|
||||
"lr_s2_access_control_key": "Long Range S2 Access Control Key",
|
||||
"lr_s2_authenticated_key": "Long Range S2 Authenticated Key",
|
||||
"s0_legacy_key": "S0 Key (Legacy)",
|
||||
"s2_access_control_key": "S2 Access Control Key",
|
||||
"s2_authenticated_key": "S2 Authenticated Key",
|
||||
"s2_unauthenticated_key": "S2 Unauthenticated Key"
|
||||
},
|
||||
"description": "Enter the security keys for your existing Z-Wave network",
|
||||
"title": "Security keys"
|
||||
},
|
||||
"configure_addon_reconfigure": {
|
||||
"data": {
|
||||
"lr_s2_access_control_key": "[%key:component::zwave_js::config::step::configure_addon_user::data::lr_s2_access_control_key%]",
|
||||
"lr_s2_authenticated_key": "[%key:component::zwave_js::config::step::configure_addon_user::data::lr_s2_authenticated_key%]",
|
||||
"s0_legacy_key": "[%key:component::zwave_js::config::step::configure_addon_user::data::s0_legacy_key%]",
|
||||
"s2_access_control_key": "[%key:component::zwave_js::config::step::configure_addon_user::data::s2_access_control_key%]",
|
||||
"s2_authenticated_key": "[%key:component::zwave_js::config::step::configure_addon_user::data::s2_authenticated_key%]",
|
||||
"s2_unauthenticated_key": "[%key:component::zwave_js::config::step::configure_addon_user::data::s2_unauthenticated_key%]",
|
||||
"lr_s2_access_control_key": "[%key:component::zwave_js::config::step::configure_security_keys::data::lr_s2_access_control_key%]",
|
||||
"lr_s2_authenticated_key": "[%key:component::zwave_js::config::step::configure_security_keys::data::lr_s2_authenticated_key%]",
|
||||
"s0_legacy_key": "[%key:component::zwave_js::config::step::configure_security_keys::data::s0_legacy_key%]",
|
||||
"s2_access_control_key": "[%key:component::zwave_js::config::step::configure_security_keys::data::s2_access_control_key%]",
|
||||
"s2_authenticated_key": "[%key:component::zwave_js::config::step::configure_security_keys::data::s2_authenticated_key%]",
|
||||
"s2_unauthenticated_key": "[%key:component::zwave_js::config::step::configure_security_keys::data::s2_unauthenticated_key%]",
|
||||
"usb_path": "[%key:common::config_flow::data::usb_path%]"
|
||||
},
|
||||
"description": "[%key:component::zwave_js::config::step::configure_addon_user::description%]",
|
||||
@ -622,5 +634,13 @@
|
||||
},
|
||||
"name": "Set a value (advanced)"
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"network_type": {
|
||||
"options": {
|
||||
"new": "It's new",
|
||||
"existing": "It already exists"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,12 +29,6 @@ from homeassistant.components.zwave_js.const import (
|
||||
CONF_ADDON_S2_ACCESS_CONTROL_KEY,
|
||||
CONF_ADDON_S2_AUTHENTICATED_KEY,
|
||||
CONF_ADDON_S2_UNAUTHENTICATED_KEY,
|
||||
CONF_LR_S2_ACCESS_CONTROL_KEY,
|
||||
CONF_LR_S2_AUTHENTICATED_KEY,
|
||||
CONF_S0_LEGACY_KEY,
|
||||
CONF_S2_ACCESS_CONTROL_KEY,
|
||||
CONF_S2_AUTHENTICATED_KEY,
|
||||
CONF_S2_UNAUTHENTICATED_KEY,
|
||||
CONF_USB_PATH,
|
||||
DOMAIN,
|
||||
)
|
||||
@ -687,7 +681,17 @@ async def test_usb_discovery(
|
||||
assert install_addon.call_args == call("core_zwave_js")
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_addon_user"
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@ -778,9 +782,18 @@ async def test_usb_discovery_addon_not_running(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_addon_user"
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
# Make sure the discovered usb device is preferred.
|
||||
data_schema = result["data_schema"]
|
||||
assert data_schema is not None
|
||||
assert data_schema({}) == {
|
||||
@ -1126,6 +1139,25 @@ async def test_discovery_addon_not_running(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -1226,6 +1258,25 @@ async def test_discovery_addon_not_installed(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -1728,6 +1779,25 @@ async def test_addon_installed(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -1822,6 +1892,25 @@ async def test_addon_installed_start_failure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -1911,6 +2000,25 @@ async def test_addon_installed_failures(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -1981,6 +2089,25 @@ async def test_addon_installed_set_options_failure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -2091,6 +2218,25 @@ async def test_addon_installed_already_configured(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/new",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -2178,6 +2324,25 @@ async def test_addon_not_installed(
|
||||
result["flow_id"],
|
||||
{
|
||||
"usb_path": "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "network_type"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"network_type": "existing",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "configure_security_keys"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"s0_legacy_key": "new123",
|
||||
"s2_access_control_key": "new456",
|
||||
"s2_authenticated_key": "new789",
|
||||
@ -4229,13 +4394,8 @@ async def test_intent_recommended_user(
|
||||
assert result["step_id"] == "configure_addon_user"
|
||||
data_schema = result["data_schema"]
|
||||
assert data_schema is not None
|
||||
assert data_schema.schema[CONF_USB_PATH] is not None
|
||||
assert data_schema.schema.get(CONF_S0_LEGACY_KEY) is None
|
||||
assert data_schema.schema.get(CONF_S2_ACCESS_CONTROL_KEY) is None
|
||||
assert data_schema.schema.get(CONF_S2_AUTHENTICATED_KEY) is None
|
||||
assert data_schema.schema.get(CONF_S2_UNAUTHENTICATED_KEY) is None
|
||||
assert data_schema.schema.get(CONF_LR_S2_ACCESS_CONTROL_KEY) is None
|
||||
assert data_schema.schema.get(CONF_LR_S2_AUTHENTICATED_KEY) is None
|
||||
assert len(data_schema.schema) == 1
|
||||
assert data_schema.schema.get(CONF_USB_PATH) is not None
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
|
Loading…
x
Reference in New Issue
Block a user