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