Add support for multiple vera controller hubs (#33613)
This commit is contained in:
parent
938e06c00e
commit
903afb62d0
24 changed files with 323 additions and 149 deletions
|
@ -2,6 +2,7 @@
|
|||
import asyncio
|
||||
from collections import defaultdict
|
||||
import logging
|
||||
from typing import Type
|
||||
|
||||
import pyvera as veraApi
|
||||
from requests.exceptions import RequestException
|
||||
|
@ -19,17 +20,25 @@ from homeassistant.const import (
|
|||
EVENT_HOMEASSISTANT_STOP,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import convert, slugify
|
||||
from homeassistant.util.dt import utc_from_timestamp
|
||||
|
||||
from .common import ControllerData, SubscriptionRegistry, get_configured_platforms
|
||||
from .common import (
|
||||
ControllerData,
|
||||
SubscriptionRegistry,
|
||||
get_configured_platforms,
|
||||
get_controller_data,
|
||||
set_controller_data,
|
||||
)
|
||||
from .config_flow import fix_device_id_list, new_options
|
||||
from .const import (
|
||||
ATTR_CURRENT_ENERGY_KWH,
|
||||
ATTR_CURRENT_POWER_W,
|
||||
CONF_CONTROLLER,
|
||||
CONF_LEGACY_UNIQUE_ID,
|
||||
DOMAIN,
|
||||
VERA_ID_FORMAT,
|
||||
)
|
||||
|
@ -54,6 +63,8 @@ CONFIG_SCHEMA = vol.Schema(
|
|||
|
||||
async def async_setup(hass: HomeAssistant, base_config: dict) -> bool:
|
||||
"""Set up for Vera controllers."""
|
||||
hass.data[DOMAIN] = {}
|
||||
|
||||
config = base_config.get(DOMAIN)
|
||||
|
||||
if not config:
|
||||
|
@ -107,10 +118,10 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
all_devices = await hass.async_add_executor_job(controller.get_devices)
|
||||
|
||||
all_scenes = await hass.async_add_executor_job(controller.get_scenes)
|
||||
except RequestException:
|
||||
except RequestException as exception:
|
||||
# There was a network related error connecting to the Vera controller.
|
||||
_LOGGER.exception("Error communicating with Vera API")
|
||||
return False
|
||||
raise ConfigEntryNotReady from exception
|
||||
|
||||
# Exclude devices unwanted by user.
|
||||
devices = [device for device in all_devices if device.device_id not in exclude_ids]
|
||||
|
@ -118,20 +129,21 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
vera_devices = defaultdict(list)
|
||||
for device in devices:
|
||||
device_type = map_vera_device(device, light_ids)
|
||||
if device_type is None:
|
||||
continue
|
||||
|
||||
vera_devices[device_type].append(device)
|
||||
if device_type is not None:
|
||||
vera_devices[device_type].append(device)
|
||||
|
||||
vera_scenes = []
|
||||
for scene in all_scenes:
|
||||
vera_scenes.append(scene)
|
||||
|
||||
controller_data = ControllerData(
|
||||
controller=controller, devices=vera_devices, scenes=vera_scenes
|
||||
controller=controller,
|
||||
devices=vera_devices,
|
||||
scenes=vera_scenes,
|
||||
config_entry=config_entry,
|
||||
)
|
||||
|
||||
hass.data[DOMAIN] = controller_data
|
||||
set_controller_data(hass, config_entry, controller_data)
|
||||
|
||||
# Forward the config data to the necessary platforms.
|
||||
for platform in get_configured_platforms(controller_data):
|
||||
|
@ -144,7 +156,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
|
||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
"""Unload Withings config entry."""
|
||||
controller_data: ControllerData = hass.data[DOMAIN]
|
||||
controller_data: ControllerData = get_controller_data(hass, config_entry)
|
||||
|
||||
tasks = [
|
||||
hass.config_entries.async_forward_entry_unload(config_entry, platform)
|
||||
|
@ -159,43 +171,52 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
|||
def map_vera_device(vera_device, remap):
|
||||
"""Map vera classes to Home Assistant types."""
|
||||
|
||||
if isinstance(vera_device, veraApi.VeraDimmer):
|
||||
return "light"
|
||||
if isinstance(vera_device, veraApi.VeraBinarySensor):
|
||||
return "binary_sensor"
|
||||
if isinstance(vera_device, veraApi.VeraSensor):
|
||||
return "sensor"
|
||||
if isinstance(vera_device, veraApi.VeraArmableDevice):
|
||||
return "switch"
|
||||
if isinstance(vera_device, veraApi.VeraLock):
|
||||
return "lock"
|
||||
if isinstance(vera_device, veraApi.VeraThermostat):
|
||||
return "climate"
|
||||
if isinstance(vera_device, veraApi.VeraCurtain):
|
||||
return "cover"
|
||||
if isinstance(vera_device, veraApi.VeraSceneController):
|
||||
return "sensor"
|
||||
if isinstance(vera_device, veraApi.VeraSwitch):
|
||||
if vera_device.device_id in remap:
|
||||
type_map = {
|
||||
veraApi.VeraDimmer: "light",
|
||||
veraApi.VeraBinarySensor: "binary_sensor",
|
||||
veraApi.VeraSensor: "sensor",
|
||||
veraApi.VeraArmableDevice: "switch",
|
||||
veraApi.VeraLock: "lock",
|
||||
veraApi.VeraThermostat: "climate",
|
||||
veraApi.VeraCurtain: "cover",
|
||||
veraApi.VeraSceneController: "sensor",
|
||||
veraApi.VeraSwitch: "switch",
|
||||
}
|
||||
|
||||
def map_special_case(instance_class: Type, entity_type: str) -> str:
|
||||
if instance_class is veraApi.VeraSwitch and vera_device.device_id in remap:
|
||||
return "light"
|
||||
return "switch"
|
||||
return None
|
||||
return entity_type
|
||||
|
||||
return next(
|
||||
iter(
|
||||
map_special_case(instance_class, entity_type)
|
||||
for instance_class, entity_type in type_map.items()
|
||||
if isinstance(vera_device, instance_class)
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
|
||||
class VeraDevice(Entity):
|
||||
"""Representation of a Vera device entity."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the device."""
|
||||
self.vera_device = vera_device
|
||||
self.controller = controller
|
||||
self.controller = controller_data.controller
|
||||
|
||||
self._name = self.vera_device.name
|
||||
# Append device id to prevent name clashes in HA.
|
||||
self.vera_id = VERA_ID_FORMAT.format(
|
||||
slugify(vera_device.name), vera_device.device_id
|
||||
slugify(vera_device.name), vera_device.vera_device_id
|
||||
)
|
||||
|
||||
if controller_data.config_entry.data.get(CONF_LEGACY_UNIQUE_ID):
|
||||
self._unique_id = str(self.vera_device.vera_device_id)
|
||||
else:
|
||||
self._unique_id = f"vera_{controller_data.config_entry.unique_id}_{self.vera_device.vera_device_id}"
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to updates."""
|
||||
self.controller.register(self.vera_device, self._update_callback)
|
||||
|
@ -254,4 +275,4 @@ class VeraDevice(Entity):
|
|||
|
||||
The Vera assigns a unique and immutable ID number to each device.
|
||||
"""
|
||||
return str(self.vera_device.vera_device_id)
|
||||
return self._unique_id
|
||||
|
|
|
@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant
|
|||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from . import VeraDevice
|
||||
from .const import DOMAIN
|
||||
from .common import ControllerData, get_controller_data
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -23,10 +23,10 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraBinarySensor(device, controller_data.controller)
|
||||
VeraBinarySensor(device, controller_data)
|
||||
for device in controller_data.devices.get(PLATFORM_DOMAIN)
|
||||
]
|
||||
)
|
||||
|
@ -35,10 +35,10 @@ async def async_setup_entry(
|
|||
class VeraBinarySensor(VeraDevice, BinarySensorEntity):
|
||||
"""Representation of a Vera Binary Sensor."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the binary_sensor."""
|
||||
self._state = False
|
||||
VeraDevice.__init__(self, vera_device, controller)
|
||||
VeraDevice.__init__(self, vera_device, controller_data)
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id)
|
||||
|
||||
@property
|
||||
|
|
|
@ -24,7 +24,7 @@ from homeassistant.helpers.entity import Entity
|
|||
from homeassistant.util import convert
|
||||
|
||||
from . import VeraDevice
|
||||
from .const import DOMAIN
|
||||
from .common import ControllerData, get_controller_data
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -40,10 +40,10 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraThermostat(device, controller_data.controller)
|
||||
VeraThermostat(device, controller_data)
|
||||
for device in controller_data.devices.get(PLATFORM_DOMAIN)
|
||||
]
|
||||
)
|
||||
|
@ -52,9 +52,9 @@ async def async_setup_entry(
|
|||
class VeraThermostat(VeraDevice, ClimateEntity):
|
||||
"""Representation of a Vera Thermostat."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the Vera device."""
|
||||
VeraDevice.__init__(self, vera_device, controller)
|
||||
VeraDevice.__init__(self, vera_device, controller_data)
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id)
|
||||
|
||||
@property
|
||||
|
|
|
@ -5,9 +5,12 @@ from typing import DefaultDict, List, NamedTuple, Set
|
|||
import pyvera as pv
|
||||
|
||||
from homeassistant.components.scene import DOMAIN as SCENE_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.event import call_later
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -17,6 +20,7 @@ class ControllerData(NamedTuple):
|
|||
controller: pv.VeraController
|
||||
devices: DefaultDict[str, List[pv.VeraDevice]]
|
||||
scenes: List[pv.VeraScene]
|
||||
config_entry: ConfigEntry
|
||||
|
||||
|
||||
def get_configured_platforms(controller_data: ControllerData) -> Set[str]:
|
||||
|
@ -31,6 +35,20 @@ def get_configured_platforms(controller_data: ControllerData) -> Set[str]:
|
|||
return set(platforms)
|
||||
|
||||
|
||||
def get_controller_data(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> ControllerData:
|
||||
"""Get controller data from hass data."""
|
||||
return hass.data[DOMAIN][config_entry.entry_id]
|
||||
|
||||
|
||||
def set_controller_data(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, data: ControllerData
|
||||
) -> None:
|
||||
"""Set controller data in hass data."""
|
||||
hass.data[DOMAIN][config_entry.entry_id] = data
|
||||
|
||||
|
||||
class SubscriptionRegistry(pv.AbstractSubscriptionRegistry):
|
||||
"""Manages polling for data from vera."""
|
||||
|
||||
|
|
|
@ -10,8 +10,13 @@ import voluptuous as vol
|
|||
from homeassistant import config_entries
|
||||
from homeassistant.const import CONF_EXCLUDE, CONF_LIGHTS, CONF_SOURCE
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.entity_registry import EntityRegistry
|
||||
|
||||
from .const import CONF_CONTROLLER, DOMAIN
|
||||
from .const import ( # pylint: disable=unused-import
|
||||
CONF_CONTROLLER,
|
||||
CONF_LEGACY_UNIQUE_ID,
|
||||
DOMAIN,
|
||||
)
|
||||
|
||||
LIST_REGEX = re.compile("[^0-9]+")
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -92,15 +97,13 @@ class VeraFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
async def async_step_user(self, user_input: dict = None):
|
||||
"""Handle user initiated flow."""
|
||||
if self.hass.config_entries.async_entries(DOMAIN):
|
||||
return self.async_abort(reason="already_configured")
|
||||
|
||||
if user_input is not None:
|
||||
return await self.async_step_finish(
|
||||
{
|
||||
**user_input,
|
||||
**options_data(user_input),
|
||||
**{CONF_SOURCE: config_entries.SOURCE_USER},
|
||||
**{CONF_LEGACY_UNIQUE_ID: False},
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -113,8 +116,29 @@ class VeraFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
async def async_step_import(self, config: dict):
|
||||
"""Handle a flow initialized by import."""
|
||||
|
||||
# If there are entities with the legacy unique_id, then this imported config
|
||||
# should also use the legacy unique_id for entity creation.
|
||||
entity_registry: EntityRegistry = (
|
||||
await self.hass.helpers.entity_registry.async_get_registry()
|
||||
)
|
||||
use_legacy_unique_id = (
|
||||
len(
|
||||
[
|
||||
entry
|
||||
for entry in entity_registry.entities.values()
|
||||
if entry.platform == DOMAIN and entry.unique_id.isdigit()
|
||||
]
|
||||
)
|
||||
> 0
|
||||
)
|
||||
|
||||
return await self.async_step_finish(
|
||||
{**config, **{CONF_SOURCE: config_entries.SOURCE_IMPORT}}
|
||||
{
|
||||
**config,
|
||||
**{CONF_SOURCE: config_entries.SOURCE_IMPORT},
|
||||
**{CONF_LEGACY_UNIQUE_ID: use_legacy_unique_id},
|
||||
}
|
||||
)
|
||||
|
||||
async def async_step_finish(self, config: dict):
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
DOMAIN = "vera"
|
||||
|
||||
CONF_CONTROLLER = "vera_controller_url"
|
||||
CONF_LEGACY_UNIQUE_ID = "legacy_unique_id"
|
||||
|
||||
VERA_ID_FORMAT = "{}_{}"
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant
|
|||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from . import VeraDevice
|
||||
from .const import DOMAIN
|
||||
from .common import ControllerData, get_controller_data
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -24,10 +24,10 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraCover(device, controller_data.controller)
|
||||
VeraCover(device, controller_data)
|
||||
for device in controller_data.devices.get(PLATFORM_DOMAIN)
|
||||
]
|
||||
)
|
||||
|
@ -36,9 +36,9 @@ async def async_setup_entry(
|
|||
class VeraCover(VeraDevice, CoverEntity):
|
||||
"""Representation a Vera Cover."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the Vera device."""
|
||||
VeraDevice.__init__(self, vera_device, controller)
|
||||
VeraDevice.__init__(self, vera_device, controller_data)
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id)
|
||||
|
||||
@property
|
||||
|
|
|
@ -17,7 +17,7 @@ from homeassistant.helpers.entity import Entity
|
|||
import homeassistant.util.color as color_util
|
||||
|
||||
from . import VeraDevice
|
||||
from .const import DOMAIN
|
||||
from .common import ControllerData, get_controller_data
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -28,10 +28,10 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraLight(device, controller_data.controller)
|
||||
VeraLight(device, controller_data)
|
||||
for device in controller_data.devices.get(PLATFORM_DOMAIN)
|
||||
]
|
||||
)
|
||||
|
@ -40,12 +40,12 @@ async def async_setup_entry(
|
|||
class VeraLight(VeraDevice, LightEntity):
|
||||
"""Representation of a Vera Light, including dimmable."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the light."""
|
||||
self._state = False
|
||||
self._color = None
|
||||
self._brightness = None
|
||||
VeraDevice.__init__(self, vera_device, controller)
|
||||
VeraDevice.__init__(self, vera_device, controller_data)
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id)
|
||||
|
||||
@property
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant
|
|||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from . import VeraDevice
|
||||
from .const import DOMAIN
|
||||
from .common import ControllerData, get_controller_data
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -27,10 +27,10 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraLock(device, controller_data.controller)
|
||||
VeraLock(device, controller_data)
|
||||
for device in controller_data.devices.get(PLATFORM_DOMAIN)
|
||||
]
|
||||
)
|
||||
|
@ -39,10 +39,10 @@ async def async_setup_entry(
|
|||
class VeraLock(VeraDevice, LockEntity):
|
||||
"""Representation of a Vera lock."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the Vera device."""
|
||||
self._state = None
|
||||
VeraDevice.__init__(self, vera_device, controller)
|
||||
VeraDevice.__init__(self, vera_device, controller_data)
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id)
|
||||
|
||||
def lock(self, **kwargs):
|
||||
|
|
|
@ -8,7 +8,8 @@ from homeassistant.core import HomeAssistant
|
|||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from .const import DOMAIN, VERA_ID_FORMAT
|
||||
from .common import ControllerData, get_controller_data
|
||||
from .const import VERA_ID_FORMAT
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -19,22 +20,19 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraScene(device, controller_data.controller)
|
||||
for device in controller_data.scenes
|
||||
]
|
||||
[VeraScene(device, controller_data) for device in controller_data.scenes]
|
||||
)
|
||||
|
||||
|
||||
class VeraScene(Scene):
|
||||
"""Representation of a Vera scene entity."""
|
||||
|
||||
def __init__(self, vera_scene, controller):
|
||||
def __init__(self, vera_scene, controller_data: ControllerData):
|
||||
"""Initialize the scene."""
|
||||
self.vera_scene = vera_scene
|
||||
self.controller = controller
|
||||
self.controller = controller_data.controller
|
||||
|
||||
self._name = self.vera_scene.name
|
||||
# Append device id to prevent name clashes in HA.
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.helpers.entity import Entity
|
|||
from homeassistant.util import convert
|
||||
|
||||
from . import VeraDevice
|
||||
from .const import DOMAIN
|
||||
from .common import ControllerData, get_controller_data
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -26,10 +26,10 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraSensor(device, controller_data.controller)
|
||||
VeraSensor(device, controller_data)
|
||||
for device in controller_data.devices.get(PLATFORM_DOMAIN)
|
||||
]
|
||||
)
|
||||
|
@ -38,12 +38,12 @@ async def async_setup_entry(
|
|||
class VeraSensor(VeraDevice, Entity):
|
||||
"""Representation of a Vera Sensor."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the sensor."""
|
||||
self.current_value = None
|
||||
self._temperature_units = None
|
||||
self.last_changed_time = None
|
||||
VeraDevice.__init__(self, vera_device, controller)
|
||||
VeraDevice.__init__(self, vera_device, controller_data)
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id)
|
||||
|
||||
@property
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "A controller is already configured.",
|
||||
"cannot_connect": "Could not connect to controller with url {base_url}"
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -13,7 +13,7 @@ from homeassistant.helpers.entity import Entity
|
|||
from homeassistant.util import convert
|
||||
|
||||
from . import VeraDevice
|
||||
from .const import DOMAIN
|
||||
from .common import ControllerData, get_controller_data
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -24,10 +24,10 @@ async def async_setup_entry(
|
|||
async_add_entities: Callable[[List[Entity], bool], None],
|
||||
) -> None:
|
||||
"""Set up the sensor config entry."""
|
||||
controller_data = hass.data[DOMAIN]
|
||||
controller_data = get_controller_data(hass, entry)
|
||||
async_add_entities(
|
||||
[
|
||||
VeraSwitch(device, controller_data.controller)
|
||||
VeraSwitch(device, controller_data)
|
||||
for device in controller_data.devices.get(PLATFORM_DOMAIN)
|
||||
]
|
||||
)
|
||||
|
@ -36,10 +36,10 @@ async def async_setup_entry(
|
|||
class VeraSwitch(VeraDevice, SwitchEntity):
|
||||
"""Representation of a Vera Switch."""
|
||||
|
||||
def __init__(self, vera_device, controller):
|
||||
def __init__(self, vera_device, controller_data: ControllerData):
|
||||
"""Initialize the Vera device."""
|
||||
self._state = False
|
||||
VeraDevice.__init__(self, vera_device, controller)
|
||||
VeraDevice.__init__(self, vera_device, controller_data)
|
||||
self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id)
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
"""Common code for tests."""
|
||||
|
||||
from enum import Enum
|
||||
from typing import Callable, Dict, NamedTuple, Tuple
|
||||
|
||||
import pyvera as pv
|
||||
|
||||
from homeassistant.components.vera.const import CONF_CONTROLLER, DOMAIN
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.vera.const import (
|
||||
CONF_CONTROLLER,
|
||||
CONF_LEGACY_UNIQUE_ID,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
@ -24,7 +29,15 @@ class ControllerData(NamedTuple):
|
|||
class ComponentData(NamedTuple):
|
||||
"""Test data about the vera component."""
|
||||
|
||||
controller_data: ControllerData
|
||||
controller_data: Tuple[ControllerData]
|
||||
|
||||
|
||||
class ConfigSource(Enum):
|
||||
"""Source of configuration."""
|
||||
|
||||
FILE = "file"
|
||||
CONFIG_FLOW = "config_flow"
|
||||
CONFIG_ENTRY = "config_entry"
|
||||
|
||||
|
||||
class ControllerConfig(NamedTuple):
|
||||
|
@ -32,31 +45,34 @@ class ControllerConfig(NamedTuple):
|
|||
|
||||
config: Dict
|
||||
options: Dict
|
||||
config_from_file: bool
|
||||
config_source: ConfigSource
|
||||
serial_number: str
|
||||
devices: Tuple[pv.VeraDevice, ...]
|
||||
scenes: Tuple[pv.VeraScene, ...]
|
||||
setup_callback: SetupCallback
|
||||
legacy_entity_unique_id: bool
|
||||
|
||||
|
||||
def new_simple_controller_config(
|
||||
config: dict = None,
|
||||
options: dict = None,
|
||||
config_from_file=False,
|
||||
config_source=ConfigSource.CONFIG_FLOW,
|
||||
serial_number="1111",
|
||||
devices: Tuple[pv.VeraDevice, ...] = (),
|
||||
scenes: Tuple[pv.VeraScene, ...] = (),
|
||||
setup_callback: SetupCallback = None,
|
||||
legacy_entity_unique_id=False,
|
||||
) -> ControllerConfig:
|
||||
"""Create simple contorller config."""
|
||||
return ControllerConfig(
|
||||
config=config or {CONF_CONTROLLER: "http://127.0.0.1:123"},
|
||||
options=options,
|
||||
config_from_file=config_from_file,
|
||||
config_source=config_source,
|
||||
serial_number=serial_number,
|
||||
devices=devices,
|
||||
scenes=scenes,
|
||||
setup_callback=setup_callback,
|
||||
legacy_entity_unique_id=legacy_entity_unique_id,
|
||||
)
|
||||
|
||||
|
||||
|
@ -68,14 +84,38 @@ class ComponentFactory:
|
|||
self.vera_controller_class_mock = vera_controller_class_mock
|
||||
|
||||
async def configure_component(
|
||||
self, hass: HomeAssistant, controller_config: ControllerConfig
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
controller_config: ControllerConfig = None,
|
||||
controller_configs: Tuple[ControllerConfig] = (),
|
||||
) -> ComponentData:
|
||||
"""Configure the component with multiple specific mock data."""
|
||||
configs = list(controller_configs)
|
||||
|
||||
if controller_config:
|
||||
configs.append(controller_config)
|
||||
|
||||
return ComponentData(
|
||||
controller_data=tuple(
|
||||
[
|
||||
await self._configure_component(hass, controller_config)
|
||||
for controller_config in configs
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
async def _configure_component(
|
||||
self, hass: HomeAssistant, controller_config: ControllerConfig
|
||||
) -> ControllerData:
|
||||
"""Configure the component with specific mock data."""
|
||||
component_config = {
|
||||
**(controller_config.config or {}),
|
||||
**(controller_config.options or {}),
|
||||
}
|
||||
|
||||
if controller_config.legacy_entity_unique_id:
|
||||
component_config[CONF_LEGACY_UNIQUE_ID] = True
|
||||
|
||||
controller = MagicMock(spec=pv.VeraController) # type: pv.VeraController
|
||||
controller.base_url = component_config.get(CONF_CONTROLLER)
|
||||
controller.register = MagicMock()
|
||||
|
@ -101,7 +141,7 @@ class ComponentFactory:
|
|||
hass_config = {}
|
||||
|
||||
# Setup component through config file import.
|
||||
if controller_config.config_from_file:
|
||||
if controller_config.config_source == ConfigSource.FILE:
|
||||
hass_config[DOMAIN] = component_config
|
||||
|
||||
# Setup Home Assistant.
|
||||
|
@ -109,9 +149,21 @@ class ComponentFactory:
|
|||
await hass.async_block_till_done()
|
||||
|
||||
# Setup component through config flow.
|
||||
if not controller_config.config_from_file:
|
||||
if controller_config.config_source == ConfigSource.CONFIG_FLOW:
|
||||
await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_USER},
|
||||
data=component_config,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Setup component directly from config entry.
|
||||
if controller_config.config_source == ConfigSource.CONFIG_ENTRY:
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN, data=component_config, options={}, unique_id="12345"
|
||||
domain=DOMAIN,
|
||||
data=controller_config.config,
|
||||
options=controller_config.options,
|
||||
unique_id="12345",
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
|
@ -124,8 +176,4 @@ class ComponentFactory:
|
|||
else None
|
||||
)
|
||||
|
||||
return ComponentData(
|
||||
controller_data=ControllerData(
|
||||
controller=controller, update_callback=update_callback
|
||||
)
|
||||
)
|
||||
return ControllerData(controller=controller, update_callback=update_callback)
|
||||
|
|
|
@ -14,7 +14,7 @@ async def test_binary_sensor(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.is_tripped = False
|
||||
entity_id = "binary_sensor.dev1_1"
|
||||
|
@ -23,7 +23,7 @@ async def test_binary_sensor(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(devices=(vera_device,)),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
vera_device.is_tripped = False
|
||||
update_callback(vera_device)
|
||||
|
|
|
@ -22,6 +22,7 @@ async def test_climate(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraThermostat) # type: pv.VeraThermostat
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = pv.CATEGORY_THERMOSTAT
|
||||
vera_device.power = 10
|
||||
|
@ -34,7 +35,7 @@ async def test_climate(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(devices=(vera_device,)),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
assert hass.states.get(entity_id).state == HVAC_MODE_OFF
|
||||
|
||||
|
@ -131,6 +132,7 @@ async def test_climate_f(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraThermostat) # type: pv.VeraThermostat
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = pv.CATEGORY_THERMOSTAT
|
||||
vera_device.power = 10
|
||||
|
@ -148,7 +150,7 @@ async def test_climate_f(
|
|||
devices=(vera_device,), setup_callback=setup_callback
|
||||
),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
|
|
|
@ -2,17 +2,13 @@
|
|||
from requests.exceptions import RequestException
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components.vera import CONF_CONTROLLER, DOMAIN
|
||||
from homeassistant.components.vera import CONF_CONTROLLER, CONF_LEGACY_UNIQUE_ID, DOMAIN
|
||||
from homeassistant.const import CONF_EXCLUDE, CONF_LIGHTS, CONF_SOURCE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import (
|
||||
RESULT_TYPE_ABORT,
|
||||
RESULT_TYPE_CREATE_ENTRY,
|
||||
RESULT_TYPE_FORM,
|
||||
)
|
||||
from homeassistant.data_entry_flow import RESULT_TYPE_CREATE_ENTRY, RESULT_TYPE_FORM
|
||||
|
||||
from tests.async_mock import MagicMock, patch
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.common import MockConfigEntry, mock_registry
|
||||
|
||||
|
||||
async def test_async_step_user_success(hass: HomeAssistant) -> None:
|
||||
|
@ -44,6 +40,7 @@ async def test_async_step_user_success(hass: HomeAssistant) -> None:
|
|||
CONF_SOURCE: config_entries.SOURCE_USER,
|
||||
CONF_LIGHTS: [12, 13],
|
||||
CONF_EXCLUDE: [14, 15],
|
||||
CONF_LEGACY_UNIQUE_ID: False,
|
||||
}
|
||||
assert result["result"].unique_id == controller.serial_number
|
||||
|
||||
|
@ -51,18 +48,6 @@ async def test_async_step_user_success(hass: HomeAssistant) -> None:
|
|||
assert entries
|
||||
|
||||
|
||||
async def test_async_step_user_already_configured(hass: HomeAssistant) -> None:
|
||||
"""Test user step with entry already configured."""
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={}, options={}, unique_id="12345")
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
async def test_async_step_import_success(hass: HomeAssistant) -> None:
|
||||
"""Test import step success."""
|
||||
with patch("pyvera.VeraController") as vera_controller_class_mock:
|
||||
|
@ -82,28 +67,40 @@ async def test_async_step_import_success(hass: HomeAssistant) -> None:
|
|||
assert result["data"] == {
|
||||
CONF_CONTROLLER: "http://127.0.0.1:123",
|
||||
CONF_SOURCE: config_entries.SOURCE_IMPORT,
|
||||
CONF_LEGACY_UNIQUE_ID: False,
|
||||
}
|
||||
assert result["result"].unique_id == controller.serial_number
|
||||
|
||||
|
||||
async def test_async_step_import_alredy_setup(hass: HomeAssistant) -> None:
|
||||
"""Test import step with entry already setup."""
|
||||
entry = MockConfigEntry(domain=DOMAIN, data={}, options={}, unique_id="12345")
|
||||
entry.add_to_hass(hass)
|
||||
async def test_async_step_import_success_with_legacy_unique_id(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test import step success with legacy unique id."""
|
||||
entity_registry = mock_registry(hass)
|
||||
entity_registry.async_get_or_create(
|
||||
domain="switch", platform=DOMAIN, unique_id="12"
|
||||
)
|
||||
|
||||
with patch("pyvera.VeraController") as vera_controller_class_mock:
|
||||
controller = MagicMock()
|
||||
controller.refresh_data = MagicMock()
|
||||
controller.serial_number = "12345"
|
||||
controller.serial_number = "serial_number_1"
|
||||
vera_controller_class_mock.return_value = controller
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={CONF_CONTROLLER: "http://localhost:445"},
|
||||
data={CONF_CONTROLLER: "http://127.0.0.1:123/"},
|
||||
)
|
||||
assert result["type"] == RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["title"] == "http://127.0.0.1:123"
|
||||
assert result["data"] == {
|
||||
CONF_CONTROLLER: "http://127.0.0.1:123",
|
||||
CONF_SOURCE: config_entries.SOURCE_IMPORT,
|
||||
CONF_LEGACY_UNIQUE_ID: True,
|
||||
}
|
||||
assert result["result"].unique_id == controller.serial_number
|
||||
|
||||
|
||||
async def test_async_step_finish_error(hass: HomeAssistant) -> None:
|
||||
|
|
|
@ -14,6 +14,7 @@ async def test_cover(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraCurtain) # type: pv.VeraCurtain
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = pv.CATEGORY_CURTAIN
|
||||
vera_device.is_closed = False
|
||||
|
@ -24,7 +25,7 @@ async def test_cover(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(devices=(vera_device,)),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
assert hass.states.get(entity_id).state == "closed"
|
||||
assert hass.states.get(entity_id).attributes["current_position"] == 0
|
||||
|
|
|
@ -12,10 +12,10 @@ from homeassistant.components.vera import (
|
|||
from homeassistant.config_entries import ENTRY_STATE_NOT_LOADED
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .common import ComponentFactory, new_simple_controller_config
|
||||
from .common import ComponentFactory, ConfigSource, new_simple_controller_config
|
||||
|
||||
from tests.async_mock import MagicMock
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.common import MockConfigEntry, mock_registry
|
||||
|
||||
|
||||
async def test_init(
|
||||
|
@ -24,7 +24,7 @@ async def test_init(
|
|||
"""Test function."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
vera_device1.is_tripped = False
|
||||
entity1_id = "binary_sensor.first_dev_1"
|
||||
|
@ -33,7 +33,7 @@ async def test_init(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
config={CONF_CONTROLLER: "http://127.0.0.1:111"},
|
||||
config_from_file=False,
|
||||
config_source=ConfigSource.CONFIG_FLOW,
|
||||
serial_number="first_serial",
|
||||
devices=(vera_device1,),
|
||||
),
|
||||
|
@ -41,8 +41,8 @@ async def test_init(
|
|||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
entry1 = entity_registry.async_get(entity1_id)
|
||||
|
||||
assert entry1
|
||||
assert entry1.unique_id == "vera_first_serial_1"
|
||||
|
||||
|
||||
async def test_init_from_file(
|
||||
|
@ -51,7 +51,7 @@ async def test_init_from_file(
|
|||
"""Test function."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
vera_device1.is_tripped = False
|
||||
entity1_id = "binary_sensor.first_dev_1"
|
||||
|
@ -60,7 +60,7 @@ async def test_init_from_file(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
config={CONF_CONTROLLER: "http://127.0.0.1:111"},
|
||||
config_from_file=True,
|
||||
config_source=ConfigSource.FILE,
|
||||
serial_number="first_serial",
|
||||
devices=(vera_device1,),
|
||||
),
|
||||
|
@ -69,6 +69,62 @@ async def test_init_from_file(
|
|||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
entry1 = entity_registry.async_get(entity1_id)
|
||||
assert entry1
|
||||
assert entry1.unique_id == "vera_first_serial_1"
|
||||
|
||||
|
||||
async def test_multiple_controllers_with_legacy_one(
|
||||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test multiple controllers with one legacy controller."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
vera_device1.is_tripped = False
|
||||
entity1_id = "binary_sensor.first_dev_1"
|
||||
|
||||
vera_device2 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device2.device_id = 2
|
||||
vera_device2.vera_device_id = vera_device2.device_id
|
||||
vera_device2.name = "second_dev"
|
||||
vera_device2.is_tripped = False
|
||||
entity2_id = "binary_sensor.second_dev_2"
|
||||
|
||||
# Add existing entity registry entry from previous setup.
|
||||
entity_registry = mock_registry(hass)
|
||||
entity_registry.async_get_or_create(
|
||||
domain="switch", platform=DOMAIN, unique_id="12"
|
||||
)
|
||||
|
||||
await vera_component_factory.configure_component(
|
||||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
config={CONF_CONTROLLER: "http://127.0.0.1:111"},
|
||||
config_source=ConfigSource.FILE,
|
||||
serial_number="first_serial",
|
||||
devices=(vera_device1,),
|
||||
),
|
||||
)
|
||||
|
||||
await vera_component_factory.configure_component(
|
||||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
config={CONF_CONTROLLER: "http://127.0.0.1:222"},
|
||||
config_source=ConfigSource.CONFIG_FLOW,
|
||||
serial_number="second_serial",
|
||||
devices=(vera_device2,),
|
||||
),
|
||||
)
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
entry1 = entity_registry.async_get(entity1_id)
|
||||
assert entry1
|
||||
assert entry1.unique_id == "1"
|
||||
|
||||
entry2 = entity_registry.async_get(entity2_id)
|
||||
assert entry2
|
||||
assert entry2.unique_id == "vera_second_serial_2"
|
||||
|
||||
|
||||
async def test_unload(
|
||||
|
@ -77,7 +133,7 @@ async def test_unload(
|
|||
"""Test function."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
vera_device1.is_tripped = False
|
||||
|
||||
|
@ -145,6 +201,7 @@ async def test_exclude_and_light_ids(
|
|||
|
||||
vera_device3 = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device3.device_id = 3
|
||||
vera_device3.vera_device_id = 3
|
||||
vera_device3.name = "dev3"
|
||||
vera_device3.category = pv.CATEGORY_SWITCH
|
||||
vera_device3.is_switched_on = MagicMock(return_value=False)
|
||||
|
@ -152,6 +209,7 @@ async def test_exclude_and_light_ids(
|
|||
|
||||
vera_device4 = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device4.device_id = 4
|
||||
vera_device4.vera_device_id = 4
|
||||
vera_device4.name = "dev4"
|
||||
vera_device4.category = pv.CATEGORY_SWITCH
|
||||
vera_device4.is_switched_on = MagicMock(return_value=False)
|
||||
|
@ -160,6 +218,7 @@ async def test_exclude_and_light_ids(
|
|||
component_data = await vera_component_factory.configure_component(
|
||||
hass=hass,
|
||||
controller_config=new_simple_controller_config(
|
||||
config_source=ConfigSource.CONFIG_ENTRY,
|
||||
devices=(vera_device1, vera_device2, vera_device3, vera_device4),
|
||||
config={**{CONF_CONTROLLER: "http://127.0.0.1:123"}, **options},
|
||||
),
|
||||
|
@ -167,12 +226,10 @@ async def test_exclude_and_light_ids(
|
|||
|
||||
# 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],
|
||||
}
|
||||
assert config_entry.options[CONF_LIGHTS] == [4, 10, 12]
|
||||
assert config_entry.options[CONF_EXCLUDE] == [1]
|
||||
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
update_callback(vera_device1)
|
||||
update_callback(vera_device2)
|
||||
|
|
|
@ -15,6 +15,7 @@ async def test_light(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraDimmer) # type: pv.VeraDimmer
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = pv.CATEGORY_DIMMER
|
||||
vera_device.is_switched_on = MagicMock(return_value=False)
|
||||
|
@ -27,7 +28,7 @@ async def test_light(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(devices=(vera_device,)),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
assert hass.states.get(entity_id).state == "off"
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ async def test_lock(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraLock) # type: pv.VeraLock
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = pv.CATEGORY_LOCK
|
||||
vera_device.is_locked = MagicMock(return_value=False)
|
||||
|
@ -24,7 +25,7 @@ async def test_lock(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(devices=(vera_device,)),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_UNLOCKED
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ async def test_scene(
|
|||
"""Test function."""
|
||||
vera_scene = MagicMock(spec=pv.VeraScene) # type: pv.VeraScene
|
||||
vera_scene.scene_id = 1
|
||||
vera_scene.vera_scene_id = vera_scene.scene_id
|
||||
vera_scene.name = "dev1"
|
||||
entity_id = "scene.dev1_1"
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ async def run_sensor_test(
|
|||
"""Test generic sensor."""
|
||||
vera_device = MagicMock(spec=pv.VeraSensor) # type: pv.VeraSensor
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = category
|
||||
setattr(vera_device, class_property, "33")
|
||||
|
@ -34,7 +35,7 @@ async def run_sensor_test(
|
|||
devices=(vera_device,), setup_callback=setup_callback
|
||||
),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
for (initial_value, state_value) in assert_states:
|
||||
setattr(vera_device, class_property, initial_value)
|
||||
|
@ -175,6 +176,7 @@ async def test_scene_controller_sensor(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraSensor) # type: pv.VeraSensor
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = pv.CATEGORY_SCENE_CONTROLLER
|
||||
vera_device.get_last_scene_id = MagicMock(return_value="id0")
|
||||
|
@ -185,7 +187,7 @@ async def test_scene_controller_sensor(
|
|||
hass=hass,
|
||||
controller_config=new_simple_controller_config(devices=(vera_device,)),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
vera_device.get_last_scene_time.return_value = "1111"
|
||||
update_callback(vera_device)
|
||||
|
|
|
@ -14,6 +14,7 @@ async def test_switch(
|
|||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.name = "dev1"
|
||||
vera_device.category = pv.CATEGORY_SWITCH
|
||||
vera_device.is_switched_on = MagicMock(return_value=False)
|
||||
|
@ -21,9 +22,11 @@ async def test_switch(
|
|||
|
||||
component_data = await vera_component_factory.configure_component(
|
||||
hass=hass,
|
||||
controller_config=new_simple_controller_config(devices=(vera_device,)),
|
||||
controller_config=new_simple_controller_config(
|
||||
devices=(vera_device,), legacy_entity_unique_id=False
|
||||
),
|
||||
)
|
||||
update_callback = component_data.controller_data.update_callback
|
||||
update_callback = component_data.controller_data[0].update_callback
|
||||
|
||||
assert hass.states.get(entity_id).state == "off"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue