mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Add reconfiguration to slide_local (#133182)
Co-authored-by: Joostlek <joostlek@outlook.com>
This commit is contained in:
parent
ca1bcbf5d5
commit
06391d4635
@ -25,9 +25,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: SlideConfigEntry) -> boo
|
|||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
|
||||||
|
entry.async_on_unload(entry.add_update_listener(update_listener))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def update_listener(hass: HomeAssistant, entry: SlideConfigEntry) -> None:
|
||||||
|
"""Handle options update."""
|
||||||
|
await hass.config_entries.async_reload(entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: SlideConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: SlideConfigEntry) -> bool:
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
@ -15,10 +15,12 @@ from goslideapi.goslideapi import (
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.zeroconf import ZeroconfServiceInfo
|
from homeassistant.components.zeroconf import ZeroconfServiceInfo
|
||||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow
|
||||||
from homeassistant.const import CONF_API_VERSION, CONF_HOST, CONF_MAC, CONF_PASSWORD
|
from homeassistant.const import CONF_API_VERSION, CONF_HOST, CONF_MAC, CONF_PASSWORD
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.device_registry import format_mac
|
from homeassistant.helpers.device_registry import format_mac
|
||||||
|
|
||||||
|
from . import SlideConfigEntry
|
||||||
from .const import CONF_INVERT_POSITION, DOMAIN
|
from .const import CONF_INVERT_POSITION, DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -34,6 +36,14 @@ class SlideConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
VERSION = 1
|
VERSION = 1
|
||||||
MINOR_VERSION = 1
|
MINOR_VERSION = 1
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@callback
|
||||||
|
def async_get_options_flow(
|
||||||
|
config_entry: SlideConfigEntry,
|
||||||
|
) -> SlideOptionsFlowHandler:
|
||||||
|
"""Get the options flow for this handler."""
|
||||||
|
return SlideOptionsFlowHandler()
|
||||||
|
|
||||||
async def async_test_connection(
|
async def async_test_connection(
|
||||||
self, user_input: dict[str, str | int]
|
self, user_input: dict[str, str | int]
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
@ -181,3 +191,26 @@ class SlideConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
"host": self._host,
|
"host": self._host,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SlideOptionsFlowHandler(OptionsFlow):
|
||||||
|
"""Handle a options flow for slide_local."""
|
||||||
|
|
||||||
|
async def async_step_init(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Manage the options."""
|
||||||
|
if user_input is not None:
|
||||||
|
return self.async_create_entry(data=user_input)
|
||||||
|
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="init",
|
||||||
|
data_schema=self.add_suggested_values_to_schema(
|
||||||
|
vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_INVERT_POSITION): bool,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{CONF_INVERT_POSITION: self.config_entry.options[CONF_INVERT_POSITION]},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@ -54,7 +54,7 @@ class SlideCoverLocal(SlideEntity, CoverEntity):
|
|||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
|
|
||||||
self._attr_name = None
|
self._attr_name = None
|
||||||
self._invert = entry.options[CONF_INVERT_POSITION]
|
self.invert = entry.options[CONF_INVERT_POSITION]
|
||||||
self._attr_unique_id = coordinator.data["mac"]
|
self._attr_unique_id = coordinator.data["mac"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -79,7 +79,7 @@ class SlideCoverLocal(SlideEntity, CoverEntity):
|
|||||||
if pos is not None:
|
if pos is not None:
|
||||||
if (1 - pos) <= DEFAULT_OFFSET or pos <= DEFAULT_OFFSET:
|
if (1 - pos) <= DEFAULT_OFFSET or pos <= DEFAULT_OFFSET:
|
||||||
pos = round(pos)
|
pos = round(pos)
|
||||||
if not self._invert:
|
if not self.invert:
|
||||||
pos = 1 - pos
|
pos = 1 - pos
|
||||||
pos = int(pos * 100)
|
pos = int(pos * 100)
|
||||||
return pos
|
return pos
|
||||||
@ -101,7 +101,7 @@ class SlideCoverLocal(SlideEntity, CoverEntity):
|
|||||||
async def async_set_cover_position(self, **kwargs: Any) -> None:
|
async def async_set_cover_position(self, **kwargs: Any) -> None:
|
||||||
"""Move the cover to a specific position."""
|
"""Move the cover to a specific position."""
|
||||||
position = kwargs[ATTR_POSITION] / 100
|
position = kwargs[ATTR_POSITION] / 100
|
||||||
if not self._invert:
|
if not self.invert:
|
||||||
position = 1 - position
|
position = 1 - position
|
||||||
|
|
||||||
if self.coordinator.data["pos"] is not None:
|
if self.coordinator.data["pos"] is not None:
|
||||||
|
@ -33,7 +33,7 @@ rules:
|
|||||||
test-coverage: todo
|
test-coverage: todo
|
||||||
integration-owner: done
|
integration-owner: done
|
||||||
docs-installation-parameters: done
|
docs-installation-parameters: done
|
||||||
docs-configuration-parameters: todo
|
docs-configuration-parameters: done
|
||||||
|
|
||||||
# Gold
|
# Gold
|
||||||
entity-translations: todo
|
entity-translations: todo
|
||||||
|
@ -27,6 +27,20 @@
|
|||||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"title": "Configure Slide",
|
||||||
|
"description": "Reconfigure the Slide device",
|
||||||
|
"data": {
|
||||||
|
"invert_position": "Invert position"
|
||||||
|
},
|
||||||
|
"data_description": {
|
||||||
|
"invert_position": "Invert the position of your slide cover."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"exceptions": {
|
"exceptions": {
|
||||||
"update_error": {
|
"update_error": {
|
||||||
"message": "Error while updating data from the API."
|
"message": "Error while updating data from the API."
|
||||||
|
@ -14,10 +14,11 @@ import pytest
|
|||||||
from homeassistant.components.slide_local.const import CONF_INVERT_POSITION, DOMAIN
|
from homeassistant.components.slide_local.const import CONF_INVERT_POSITION, DOMAIN
|
||||||
from homeassistant.components.zeroconf import ZeroconfServiceInfo
|
from homeassistant.components.zeroconf import ZeroconfServiceInfo
|
||||||
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
||||||
from homeassistant.const import CONF_API_VERSION, CONF_HOST, CONF_PASSWORD
|
from homeassistant.const import CONF_API_VERSION, CONF_HOST, CONF_PASSWORD, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
|
from . import setup_platform
|
||||||
from .const import HOST, SLIDE_INFO_DATA
|
from .const import HOST, SLIDE_INFO_DATA
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
@ -371,3 +372,27 @@ async def test_zeroconf_connection_error(
|
|||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == "discovery_connection_failed"
|
assert result["reason"] == "discovery_connection_failed"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_options_flow(
|
||||||
|
hass: HomeAssistant, mock_slide_api: AsyncMock, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
|
"""Test options flow works correctly."""
|
||||||
|
await setup_platform(hass, mock_config_entry, [Platform.COVER])
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_init(mock_config_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={
|
||||||
|
CONF_INVERT_POSITION: True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
assert mock_config_entry.options == {
|
||||||
|
CONF_INVERT_POSITION: True,
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user