allow overriding host api url in config flow (#33481)
* allow overriding host api url in config flow * fix typo * capitalize URLpull/33488/head
parent
b892dbc6ea
commit
955c94e313
|
@ -33,6 +33,9 @@
|
|||
"abort": {
|
||||
"not_konn_panel": "Not a recognized Konnected.io device"
|
||||
},
|
||||
"error": {
|
||||
"bad_host": "Invalid Override API host url"
|
||||
},
|
||||
"step": {
|
||||
"options_binary": {
|
||||
"data": {
|
||||
|
@ -82,7 +85,9 @@
|
|||
},
|
||||
"options_misc": {
|
||||
"data": {
|
||||
"blink": "Blink panel LED on when sending state change"
|
||||
"api_host": "Override API host URL (optional)",
|
||||
"blink": "Blink panel LED on when sending state change",
|
||||
"override_api_host": "Override default Home Assistant API host panel URL"
|
||||
},
|
||||
"description": "Please select the desired behavior for your panel",
|
||||
"title": "Configure Misc"
|
||||
|
|
|
@ -91,7 +91,7 @@ def ensure_zone(value):
|
|||
return str(value)
|
||||
|
||||
|
||||
def import_validator(config):
|
||||
def import_device_validator(config):
|
||||
"""Validate zones and reformat for import."""
|
||||
config = copy.deepcopy(config)
|
||||
io_cfgs = {}
|
||||
|
@ -117,10 +117,22 @@ def import_validator(config):
|
|||
config.pop(CONF_SWITCHES, None)
|
||||
config.pop(CONF_BLINK, None)
|
||||
config.pop(CONF_DISCOVERY, None)
|
||||
config.pop(CONF_API_HOST, None)
|
||||
config.pop(CONF_IO, None)
|
||||
return config
|
||||
|
||||
|
||||
def import_validator(config):
|
||||
"""Reformat for import."""
|
||||
config = copy.deepcopy(config)
|
||||
|
||||
# push api_host into device configs
|
||||
for device in config.get(CONF_DEVICES, []):
|
||||
device[CONF_API_HOST] = config.get(CONF_API_HOST, "")
|
||||
|
||||
return config
|
||||
|
||||
|
||||
# configuration.yaml schemas (legacy)
|
||||
BINARY_SENSOR_SCHEMA_YAML = vol.All(
|
||||
vol.Schema(
|
||||
|
@ -179,23 +191,27 @@ DEVICE_SCHEMA_YAML = vol.All(
|
|||
vol.Inclusive(CONF_HOST, "host_info"): cv.string,
|
||||
vol.Inclusive(CONF_PORT, "host_info"): cv.port,
|
||||
vol.Optional(CONF_BLINK, default=True): cv.boolean,
|
||||
vol.Optional(CONF_API_HOST, default=""): vol.Any("", cv.url),
|
||||
vol.Optional(CONF_DISCOVERY, default=True): cv.boolean,
|
||||
}
|
||||
),
|
||||
import_validator,
|
||||
import_device_validator,
|
||||
)
|
||||
|
||||
# pylint: disable=no-value-for-parameter
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_ACCESS_TOKEN): cv.string,
|
||||
vol.Optional(CONF_API_HOST): vol.Url(),
|
||||
vol.Optional(CONF_DEVICES): vol.All(
|
||||
cv.ensure_list, [DEVICE_SCHEMA_YAML]
|
||||
),
|
||||
}
|
||||
DOMAIN: vol.All(
|
||||
import_validator,
|
||||
vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_ACCESS_TOKEN): cv.string,
|
||||
vol.Optional(CONF_API_HOST): vol.Url(),
|
||||
vol.Optional(CONF_DEVICES): vol.All(
|
||||
cv.ensure_list, [DEVICE_SCHEMA_YAML]
|
||||
),
|
||||
}
|
||||
),
|
||||
)
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
|
|
|
@ -31,6 +31,7 @@ from homeassistant.helpers import config_validation as cv
|
|||
|
||||
from .const import (
|
||||
CONF_ACTIVATION,
|
||||
CONF_API_HOST,
|
||||
CONF_BLINK,
|
||||
CONF_DEFAULT_OPTIONS,
|
||||
CONF_DISCOVERY,
|
||||
|
@ -61,6 +62,8 @@ CONF_MORE_STATES = "more_states"
|
|||
CONF_YES = "Yes"
|
||||
CONF_NO = "No"
|
||||
|
||||
CONF_OVERRIDE_API_HOST = "override_api_host"
|
||||
|
||||
KONN_MANUFACTURER = "konnected.io"
|
||||
KONN_PANEL_MODEL_NAMES = {
|
||||
KONN_MODEL: "Konnected Alarm Panel",
|
||||
|
@ -138,6 +141,7 @@ OPTIONS_SCHEMA = vol.Schema(
|
|||
vol.Optional(CONF_SENSORS): vol.All(cv.ensure_list, [SENSOR_SCHEMA]),
|
||||
vol.Optional(CONF_SWITCHES): vol.All(cv.ensure_list, [SWITCH_SCHEMA]),
|
||||
vol.Optional(CONF_BLINK, default=True): cv.boolean,
|
||||
vol.Optional(CONF_API_HOST, default=""): vol.Any("", cv.url),
|
||||
vol.Optional(CONF_DISCOVERY, default=True): cv.boolean,
|
||||
},
|
||||
extra=vol.REMOVE_EXTRA,
|
||||
|
@ -785,8 +789,19 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||
"""Allow the user to configure the LED behavior."""
|
||||
errors = {}
|
||||
if user_input is not None:
|
||||
self.new_opt[CONF_BLINK] = user_input[CONF_BLINK]
|
||||
return self.async_create_entry(title="", data=self.new_opt)
|
||||
# config schema only does basic schema val so check url here
|
||||
try:
|
||||
if user_input[CONF_OVERRIDE_API_HOST]:
|
||||
cv.url(user_input.get(CONF_API_HOST, ""))
|
||||
else:
|
||||
user_input[CONF_API_HOST] = ""
|
||||
except vol.Invalid:
|
||||
errors["base"] = "bad_host"
|
||||
else:
|
||||
# no need to store the override - can infer
|
||||
del user_input[CONF_OVERRIDE_API_HOST]
|
||||
self.new_opt.update(user_input)
|
||||
return self.async_create_entry(title="", data=self.new_opt)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="options_misc",
|
||||
|
@ -795,6 +810,13 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||
vol.Required(
|
||||
CONF_BLINK, default=self.current_opt.get(CONF_BLINK, True)
|
||||
): bool,
|
||||
vol.Required(
|
||||
CONF_OVERRIDE_API_HOST,
|
||||
default=bool(self.current_opt.get(CONF_API_HOST)),
|
||||
): bool,
|
||||
vol.Optional(
|
||||
CONF_API_HOST, default=self.current_opt.get(CONF_API_HOST, "")
|
||||
): str,
|
||||
}
|
||||
),
|
||||
errors=errors,
|
||||
|
|
|
@ -294,7 +294,9 @@ class AlarmPanel:
|
|||
@callback
|
||||
def async_desired_settings_payload(self):
|
||||
"""Return a dict representing the desired device configuration."""
|
||||
desired_api_host = (
|
||||
# keeping self.hass.data check for backwards compatibility
|
||||
# newly configured integrations store this in the config entry
|
||||
desired_api_host = self.options.get(CONF_API_HOST) or (
|
||||
self.hass.data[DOMAIN].get(CONF_API_HOST) or self.hass.config.api.base_url
|
||||
)
|
||||
desired_api_endpoint = desired_api_host + ENDPOINT_ROOT
|
||||
|
|
|
@ -94,11 +94,15 @@
|
|||
"title": "Configure Misc",
|
||||
"description": "Please select the desired behavior for your panel",
|
||||
"data": {
|
||||
"blink": "Blink panel LED on when sending state change"
|
||||
"blink": "Blink panel LED on when sending state change",
|
||||
"override_api_host": "Override default Home Assistant API host panel URL",
|
||||
"api_host": "Override API host URL (optional)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {},
|
||||
"error": {
|
||||
"bad_host": "Invalid Override API host url"
|
||||
},
|
||||
"abort": {
|
||||
"not_konn_panel": "Not a recognized Konnected.io device"
|
||||
}
|
||||
|
|
|
@ -450,6 +450,7 @@ async def test_import_existing_config(hass, mock_panel):
|
|||
"alarm1": "Switchable Output",
|
||||
},
|
||||
"blink": True,
|
||||
"api_host": "",
|
||||
"discovery": True,
|
||||
"binary_sensors": [
|
||||
{"zone": "2", "type": "door", "inverse": False},
|
||||
|
@ -628,6 +629,7 @@ async def test_import_pin_config(hass, mock_panel):
|
|||
"out": "Switchable Output",
|
||||
},
|
||||
"blink": True,
|
||||
"api_host": "",
|
||||
"discovery": True,
|
||||
"binary_sensors": [
|
||||
{"zone": "1", "type": "door", "inverse": False},
|
||||
|
@ -778,9 +780,21 @@ async def test_option_flow(hass, mock_panel):
|
|||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "options_misc"
|
||||
|
||||
# make sure we enforce url format
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={"blink": True},
|
||||
result["flow_id"],
|
||||
user_input={"blink": True, "override_api_host": True, "api_host": "badhosturl"},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "options_misc"
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
"blink": True,
|
||||
"override_api_host": True,
|
||||
"api_host": "http://overridehost:1111",
|
||||
},
|
||||
)
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["data"] == {
|
||||
|
@ -792,6 +806,7 @@ async def test_option_flow(hass, mock_panel):
|
|||
"out": "Switchable Output",
|
||||
},
|
||||
"blink": True,
|
||||
"api_host": "http://overridehost:1111",
|
||||
"binary_sensors": [
|
||||
{"zone": "2", "type": "door", "inverse": False},
|
||||
{"zone": "6", "type": "window", "name": "winder", "inverse": True},
|
||||
|
@ -958,7 +973,7 @@ async def test_option_flow_pro(hass, mock_panel):
|
|||
assert result["step_id"] == "options_misc"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={"blink": True},
|
||||
result["flow_id"], user_input={"blink": True, "override_api_host": False},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
|
@ -976,6 +991,7 @@ async def test_option_flow_pro(hass, mock_panel):
|
|||
"out1": "Switchable Output",
|
||||
},
|
||||
"blink": True,
|
||||
"api_host": "",
|
||||
"binary_sensors": [
|
||||
{"zone": "2", "type": "door", "inverse": False},
|
||||
{"zone": "6", "type": "window", "name": "winder", "inverse": True},
|
||||
|
@ -1121,7 +1137,7 @@ async def test_option_flow_import(hass, mock_panel):
|
|||
schema = result["data_schema"]({})
|
||||
assert schema["blink"] is True
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={"blink": False},
|
||||
result["flow_id"], user_input={"blink": False, "override_api_host": False},
|
||||
)
|
||||
|
||||
# verify the updated fields
|
||||
|
@ -1129,6 +1145,7 @@ async def test_option_flow_import(hass, mock_panel):
|
|||
assert result["data"] == {
|
||||
"io": {"1": "Binary Sensor", "2": "Digital Sensor", "3": "Switchable Output"},
|
||||
"blink": False,
|
||||
"api_host": "",
|
||||
"binary_sensors": [
|
||||
{"zone": "1", "type": "door", "inverse": True, "name": "winder"},
|
||||
],
|
||||
|
|
|
@ -43,6 +43,7 @@ async def test_config_schema(hass):
|
|||
"""Test that config schema is imported properly."""
|
||||
config = {
|
||||
konnected.DOMAIN: {
|
||||
konnected.CONF_API_HOST: "http://1.1.1.1:8888",
|
||||
konnected.CONF_ACCESS_TOKEN: "abcdefgh",
|
||||
konnected.CONF_DEVICES: [{konnected.CONF_ID: "aabbccddeeff"}],
|
||||
}
|
||||
|
@ -50,10 +51,12 @@ async def test_config_schema(hass):
|
|||
assert konnected.CONFIG_SCHEMA(config) == {
|
||||
"konnected": {
|
||||
"access_token": "abcdefgh",
|
||||
"api_host": "http://1.1.1.1:8888",
|
||||
"devices": [
|
||||
{
|
||||
"default_options": {
|
||||
"blink": True,
|
||||
"api_host": "http://1.1.1.1:8888",
|
||||
"discovery": True,
|
||||
"io": {
|
||||
"1": "Disabled",
|
||||
|
@ -96,6 +99,7 @@ async def test_config_schema(hass):
|
|||
{
|
||||
"default_options": {
|
||||
"blink": True,
|
||||
"api_host": "",
|
||||
"discovery": True,
|
||||
"io": {
|
||||
"1": "Disabled",
|
||||
|
@ -162,6 +166,7 @@ async def test_config_schema(hass):
|
|||
{
|
||||
"default_options": {
|
||||
"blink": True,
|
||||
"api_host": "",
|
||||
"discovery": True,
|
||||
"io": {
|
||||
"1": "Binary Sensor",
|
||||
|
|
Loading…
Reference in New Issue