Add options flow to enigma2 (#115795)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>pull/119331/head
parent
4a9ebd9af1
commit
6184fd26d3
|
@ -1,6 +1,6 @@
|
|||
"""Config flow for Enigma2."""
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
|
||||
from aiohttp.client_exceptions import ClientError
|
||||
from openwebif.api import OpenWebIfDevice
|
||||
|
@ -8,7 +8,12 @@ from openwebif.error import InvalidAuthError
|
|||
import voluptuous as vol
|
||||
from yarl import URL
|
||||
|
||||
from homeassistant.config_entries import SOURCE_USER, ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_USER,
|
||||
ConfigEntry,
|
||||
ConfigFlow,
|
||||
ConfigFlowResult,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PASSWORD,
|
||||
|
@ -17,10 +22,15 @@ from homeassistant.const import (
|
|||
CONF_USERNAME,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback
|
||||
from homeassistant.helpers import selector
|
||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaCommonFlowHandler,
|
||||
SchemaFlowFormStep,
|
||||
SchemaOptionsFlowHandler,
|
||||
)
|
||||
|
||||
from .const import (
|
||||
CONF_DEEP_STANDBY,
|
||||
|
@ -55,6 +65,32 @@ CONFIG_SCHEMA = vol.Schema(
|
|||
)
|
||||
|
||||
|
||||
async def get_options_schema(handler: SchemaCommonFlowHandler) -> vol.Schema:
|
||||
"""Get the options schema."""
|
||||
hass = handler.parent_handler.hass
|
||||
entry = cast(SchemaOptionsFlowHandler, handler.parent_handler).config_entry
|
||||
device: OpenWebIfDevice = hass.data[DOMAIN][entry.entry_id]
|
||||
bouquets = [b[1] for b in (await device.get_all_bouquets())["bouquets"]]
|
||||
|
||||
return vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_DEEP_STANDBY): selector.BooleanSelector(),
|
||||
vol.Optional(CONF_SOURCE_BOUQUET): selector.SelectSelector(
|
||||
selector.SelectSelectorConfig(
|
||||
options=bouquets,
|
||||
mode=selector.SelectSelectorMode.DROPDOWN,
|
||||
)
|
||||
),
|
||||
vol.Optional(CONF_USE_CHANNEL_ICON): selector.BooleanSelector(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
OPTIONS_FLOW = {
|
||||
"init": SchemaFlowFormStep(get_options_schema),
|
||||
}
|
||||
|
||||
|
||||
class Enigma2ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Enigma2."""
|
||||
|
||||
|
@ -163,3 +199,9 @@ class Enigma2ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
return self.async_create_entry(
|
||||
data=data, title=data[CONF_HOST], options=options
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(config_entry: ConfigEntry) -> SchemaOptionsFlowHandler:
|
||||
"""Get the options flow for this handler."""
|
||||
return SchemaOptionsFlowHandler(config_entry, OPTIONS_FLOW)
|
||||
|
|
|
@ -26,6 +26,20 @@
|
|||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"data": {
|
||||
"deep_standby": "Turn off to Deep Standby",
|
||||
"source_bouquet": "Bouquet to use as media source",
|
||||
"use_channel_icon": "Show channel icon as media image"
|
||||
},
|
||||
"data_description": {
|
||||
"deep_standby": "Turn off the device to Deep Standby (shutdown) instead of standby mode."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
"deprecated_yaml_import_issue_unknown": {
|
||||
"title": "The Enigma2 YAML configuration import failed",
|
||||
|
|
|
@ -86,5 +86,16 @@ class MockDevice:
|
|||
"""Get mock about endpoint."""
|
||||
return await self._call_api("/api/about")
|
||||
|
||||
async def get_all_bouquets(self) -> dict:
|
||||
"""Get all bouquets."""
|
||||
return {
|
||||
"bouquets": [
|
||||
[
|
||||
'1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet',
|
||||
"Favourites (TV)",
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
async def close(self):
|
||||
"""Mock close."""
|
||||
|
|
|
@ -23,6 +23,8 @@ from .conftest import (
|
|||
MockDevice,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def user_flow(hass: HomeAssistant) -> str:
|
||||
|
@ -164,3 +166,34 @@ async def test_form_import_errors(
|
|||
assert issue.issue_domain == DOMAIN
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == error_type
|
||||
|
||||
|
||||
async def test_options_flow(hass: HomeAssistant, user_flow: str):
|
||||
"""Test the form options."""
|
||||
|
||||
with patch(
|
||||
"openwebif.api.OpenWebIfDevice.__new__",
|
||||
return_value=MockDevice(),
|
||||
):
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=TEST_FULL, options={}, entry_id="1")
|
||||
entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is config_entries.ConfigEntryState.LOADED
|
||||
|
||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={"source_bouquet": "Favourites (TV)"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert entry.options == {"source_bouquet": "Favourites (TV)"}
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is config_entries.ConfigEntryState.LOADED
|
||||
|
|
Loading…
Reference in New Issue