mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Fix vera config ids not being converted to integers (#35070)
This commit is contained in:
parent
88b7aba1c8
commit
ab08c1bef8
@ -25,7 +25,7 @@ from homeassistant.util import convert, slugify
|
||||
from homeassistant.util.dt import utc_from_timestamp
|
||||
|
||||
from .common import ControllerData, get_configured_platforms
|
||||
from .config_flow import new_options
|
||||
from .config_flow import fix_device_id_list, new_options
|
||||
from .const import (
|
||||
ATTR_CURRENT_ENERGY_KWH,
|
||||
ATTR_CURRENT_POWER_W,
|
||||
@ -81,9 +81,18 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
||||
),
|
||||
)
|
||||
|
||||
saved_light_ids = config_entry.options.get(CONF_LIGHTS, [])
|
||||
saved_exclude_ids = config_entry.options.get(CONF_EXCLUDE, [])
|
||||
|
||||
base_url = config_entry.data[CONF_CONTROLLER]
|
||||
light_ids = config_entry.options.get(CONF_LIGHTS, [])
|
||||
exclude_ids = config_entry.options.get(CONF_EXCLUDE, [])
|
||||
light_ids = fix_device_id_list(saved_light_ids)
|
||||
exclude_ids = fix_device_id_list(saved_exclude_ids)
|
||||
|
||||
# If the ids were corrected. Update the config entry.
|
||||
if light_ids != saved_light_ids or exclude_ids != saved_exclude_ids:
|
||||
hass.config_entries.async_update_entry(
|
||||
entry=config_entry, options=new_options(light_ids, exclude_ids)
|
||||
)
|
||||
|
||||
# Initialize the Vera controller.
|
||||
controller = veraApi.VeraController(base_url)
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Config flow for Vera."""
|
||||
import logging
|
||||
import re
|
||||
from typing import List, cast
|
||||
from typing import Any, List
|
||||
|
||||
import pyvera as pv
|
||||
from requests.exceptions import RequestException
|
||||
@ -17,20 +17,22 @@ LIST_REGEX = re.compile("[^0-9]+")
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def str_to_int_list(data: str) -> List[str]:
|
||||
def fix_device_id_list(data: List[Any]) -> List[int]:
|
||||
"""Fix the id list by converting it to a supported int list."""
|
||||
return str_to_int_list(list_to_str(data))
|
||||
|
||||
|
||||
def str_to_int_list(data: str) -> List[int]:
|
||||
"""Convert a string to an int list."""
|
||||
if isinstance(str, list):
|
||||
return cast(List[str], data)
|
||||
|
||||
return [s for s in LIST_REGEX.split(data) if len(s) > 0]
|
||||
return [int(s) for s in LIST_REGEX.split(data) if len(s) > 0]
|
||||
|
||||
|
||||
def int_list_to_str(data: List[str]) -> str:
|
||||
def list_to_str(data: List[Any]) -> str:
|
||||
"""Convert an int list to a string."""
|
||||
return " ".join([str(i) for i in data])
|
||||
|
||||
|
||||
def new_options(lights: List[str], exclude: List[str]) -> dict:
|
||||
def new_options(lights: List[int], exclude: List[int]) -> dict:
|
||||
"""Create a standard options object."""
|
||||
return {CONF_LIGHTS: lights, CONF_EXCLUDE: exclude}
|
||||
|
||||
@ -40,10 +42,10 @@ def options_schema(options: dict = None) -> dict:
|
||||
options = options or {}
|
||||
return {
|
||||
vol.Optional(
|
||||
CONF_LIGHTS, default=int_list_to_str(options.get(CONF_LIGHTS, [])),
|
||||
CONF_LIGHTS, default=list_to_str(options.get(CONF_LIGHTS, [])),
|
||||
): str,
|
||||
vol.Optional(
|
||||
CONF_EXCLUDE, default=int_list_to_str(options.get(CONF_EXCLUDE, [])),
|
||||
CONF_EXCLUDE, default=list_to_str(options.get(CONF_EXCLUDE, [])),
|
||||
): str,
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,8 @@ async def test_async_step_user_success(hass: HomeAssistant) -> None:
|
||||
assert result["data"] == {
|
||||
CONF_CONTROLLER: "http://127.0.0.1:123",
|
||||
CONF_SOURCE: config_entries.SOURCE_USER,
|
||||
CONF_LIGHTS: ["12", "13"],
|
||||
CONF_EXCLUDE: ["14", "15"],
|
||||
CONF_LIGHTS: [12, 13],
|
||||
CONF_EXCLUDE: [14, 15],
|
||||
}
|
||||
assert result["result"].unique_id == controller.serial_number
|
||||
|
||||
@ -154,6 +154,6 @@ async def test_options(hass):
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
CONF_LIGHTS: ["1", "2", "3", "4", "5", "6", "7"],
|
||||
CONF_EXCLUDE: ["8", "9", "10", "11", "12", "13", "14"],
|
||||
CONF_LIGHTS: [1, 2, 3, 4, 5, 6, 7],
|
||||
CONF_EXCLUDE: [8, 9, 10, 11, 12, 13, 14],
|
||||
}
|
||||
|
@ -1,8 +1,14 @@
|
||||
"""Vera tests."""
|
||||
import pytest
|
||||
import pyvera as pv
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
from homeassistant.components.vera import CONF_CONTROLLER, DOMAIN
|
||||
from homeassistant.components.vera import (
|
||||
CONF_CONTROLLER,
|
||||
CONF_EXCLUDE,
|
||||
CONF_LIGHTS,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import ENTRY_STATE_NOT_LOADED
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
@ -110,3 +116,71 @@ async def test_async_setup_entry_error(
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
assert not await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
["options"],
|
||||
[
|
||||
[{CONF_LIGHTS: [4, 10, 12, "AAA"], CONF_EXCLUDE: [1, "BBB"]}],
|
||||
[{CONF_LIGHTS: ["4", "10", "12", "AAA"], CONF_EXCLUDE: ["1", "BBB"]}],
|
||||
],
|
||||
)
|
||||
async def test_exclude_and_light_ids(
|
||||
hass: HomeAssistant, vera_component_factory: ComponentFactory, options
|
||||
) -> None:
|
||||
"""Test device exclusion, marking switches as lights and fixing the data type."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = 1
|
||||
vera_device1.name = "dev1"
|
||||
vera_device1.is_tripped = False
|
||||
entity_id1 = "binary_sensor.dev1_1"
|
||||
|
||||
vera_device2 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device2.device_id = 2
|
||||
vera_device2.vera_device_id = 2
|
||||
vera_device2.name = "dev2"
|
||||
vera_device2.is_tripped = False
|
||||
entity_id2 = "binary_sensor.dev2_2"
|
||||
|
||||
vera_device3 = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device3.device_id = 3
|
||||
vera_device3.name = "dev3"
|
||||
vera_device3.category = pv.CATEGORY_SWITCH
|
||||
vera_device3.is_switched_on = MagicMock(return_value=False)
|
||||
entity_id3 = "switch.dev3_3"
|
||||
|
||||
vera_device4 = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device4.device_id = 4
|
||||
vera_device4.name = "dev4"
|
||||
vera_device4.category = pv.CATEGORY_SWITCH
|
||||
vera_device4.is_switched_on = MagicMock(return_value=False)
|
||||
entity_id4 = "light.dev4_4"
|
||||
|
||||
component_data = await vera_component_factory.configure_component(
|
||||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
devices=(vera_device1, vera_device2, vera_device3, vera_device4),
|
||||
config={**{CONF_CONTROLLER: "http://127.0.0.1:123"}, **options},
|
||||
),
|
||||
)
|
||||
|
||||
# Assert the entries were setup correctly.
|
||||
config_entry = next(iter(hass.config_entries.async_entries(DOMAIN)))
|
||||
assert config_entry.options == {
|
||||
CONF_LIGHTS: [4, 10, 12],
|
||||
CONF_EXCLUDE: [1],
|
||||
}
|
||||
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
|
||||
update_callback(vera_device1)
|
||||
update_callback(vera_device2)
|
||||
update_callback(vera_device3)
|
||||
update_callback(vera_device4)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(entity_id1) is None
|
||||
assert hass.states.get(entity_id2) is not None
|
||||
assert hass.states.get(entity_id3) is not None
|
||||
assert hass.states.get(entity_id4) is not None
|
||||
|
Loading…
x
Reference in New Issue
Block a user