Pass in parameters explicitly to DeconzSession (#29617)

Dont pass in loop to DeconzSession
Services will use new refresh state method
pull/29660/head
Robert Svensson 2019-12-08 16:53:34 +01:00 committed by GitHub
parent 00dc721609
commit 57a3f7d5c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 219 additions and 137 deletions

View File

@ -26,10 +26,10 @@ SUPPORTED_PLATFORMS = [
"switch", "switch",
] ]
NEW_GROUP = "group" NEW_GROUP = "groups"
NEW_LIGHT = "light" NEW_LIGHT = "lights"
NEW_SCENE = "scene" NEW_SCENE = "scenes"
NEW_SENSOR = "sensor" NEW_SENSOR = "sensors"
NEW_DEVICE = { NEW_DEVICE = {
NEW_GROUP: "deconz_new_group_{}", NEW_GROUP: "deconz_new_group_{}",

View File

@ -4,7 +4,7 @@ import asyncio
import async_timeout import async_timeout
from pydeconz import DeconzSession, errors from pydeconz import DeconzSession, errors
from homeassistant.const import CONF_HOST from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
@ -42,13 +42,13 @@ def get_gateway_from_config_entry(hass, config_entry):
class DeconzGateway: class DeconzGateway:
"""Manages a single deCONZ gateway.""" """Manages a single deCONZ gateway."""
def __init__(self, hass, config_entry): def __init__(self, hass, config_entry) -> None:
"""Initialize the system.""" """Initialize the system."""
self.hass = hass self.hass = hass
self.config_entry = config_entry self.config_entry = config_entry
self.available = True self.available = True
self.api = None self.api = None
self.deconz_ids = {} self.deconz_ids = {}
self.events = [] self.events = []
self.listeners = [] self.listeners = []
@ -77,7 +77,7 @@ class DeconzGateway:
CONF_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS CONF_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS
) )
async def async_update_device_registry(self): async def async_update_device_registry(self) -> None:
"""Update device registry.""" """Update device registry."""
device_registry = await self.hass.helpers.device_registry.async_get_registry() device_registry = await self.hass.helpers.device_registry.async_get_registry()
device_registry.async_get_or_create( device_registry.async_get_or_create(
@ -90,7 +90,7 @@ class DeconzGateway:
sw_version=self.api.config.swversion, sw_version=self.api.config.swversion,
) )
async def async_setup(self): async def async_setup(self) -> bool:
"""Set up a deCONZ gateway.""" """Set up a deCONZ gateway."""
hass = self.hass hass = self.hass
@ -105,8 +105,8 @@ class DeconzGateway:
except CannotConnect: except CannotConnect:
raise ConfigEntryNotReady raise ConfigEntryNotReady
except Exception: # pylint: disable=broad-except except Exception as err: # pylint: disable=broad-except
_LOGGER.error("Error connecting with deCONZ gateway") _LOGGER.error("Error connecting with deCONZ gateway: %s", err)
return False return False
for component in SUPPORTED_PLATFORMS: for component in SUPPORTED_PLATFORMS:
@ -124,7 +124,7 @@ class DeconzGateway:
return True return True
@staticmethod @staticmethod
async def async_new_address(hass, entry): async def async_new_address(hass, entry) -> None:
"""Handle signals of gateway getting new address. """Handle signals of gateway getting new address.
This is a static method because a class method (bound method), This is a static method because a class method (bound method),
@ -137,23 +137,23 @@ class DeconzGateway:
gateway.api.start() gateway.api.start()
@property @property
def signal_reachable(self): def signal_reachable(self) -> str:
"""Gateway specific event to signal a change in connection status.""" """Gateway specific event to signal a change in connection status."""
return f"deconz-reachable-{self.bridgeid}" return f"deconz-reachable-{self.bridgeid}"
@callback @callback
def async_connection_status_callback(self, available): def async_connection_status_callback(self, available) -> None:
"""Handle signals of gateway connection status.""" """Handle signals of gateway connection status."""
self.available = available self.available = available
async_dispatcher_send(self.hass, self.signal_reachable, True) async_dispatcher_send(self.hass, self.signal_reachable, True)
@property @property
def signal_options_update(self): def signal_options_update(self) -> str:
"""Event specific per deCONZ entry to signal new options.""" """Event specific per deCONZ entry to signal new options."""
return f"deconz-options-{self.bridgeid}" return f"deconz-options-{self.bridgeid}"
@staticmethod @staticmethod
async def async_options_updated(hass, entry): async def async_options_updated(hass, entry) -> None:
"""Triggered by config entry options updates.""" """Triggered by config entry options updates."""
gateway = get_gateway_from_config_entry(hass, entry) gateway = get_gateway_from_config_entry(hass, entry)
@ -161,12 +161,12 @@ class DeconzGateway:
async_dispatcher_send(hass, gateway.signal_options_update, registry) async_dispatcher_send(hass, gateway.signal_options_update, registry)
@callback @callback
def async_signal_new_device(self, device_type): def async_signal_new_device(self, device_type) -> str:
"""Gateway specific event to signal new device.""" """Gateway specific event to signal new device."""
return NEW_DEVICE[device_type].format(self.bridgeid) return NEW_DEVICE[device_type].format(self.bridgeid)
@callback @callback
def async_add_device_callback(self, device_type, device): def async_add_device_callback(self, device_type, device) -> None:
"""Handle event of new device creation in deCONZ.""" """Handle event of new device creation in deCONZ."""
if not isinstance(device, list): if not isinstance(device, list):
device = [device] device = [device]
@ -175,7 +175,7 @@ class DeconzGateway:
) )
@callback @callback
def shutdown(self, event): def shutdown(self, event) -> None:
"""Wrap the call to deconz.close. """Wrap the call to deconz.close.
Used as an argument to EventBus.async_listen_once. Used as an argument to EventBus.async_listen_once.
@ -206,20 +206,21 @@ class DeconzGateway:
async def get_gateway( async def get_gateway(
hass, config, async_add_device_callback, async_connection_status_callback hass, config, async_add_device_callback, async_connection_status_callback
): ) -> DeconzSession:
"""Create a gateway object and verify configuration.""" """Create a gateway object and verify configuration."""
session = aiohttp_client.async_get_clientsession(hass) session = aiohttp_client.async_get_clientsession(hass)
deconz = DeconzSession( deconz = DeconzSession(
hass.loop,
session, session,
**config, config[CONF_HOST],
config[CONF_PORT],
config[CONF_API_KEY],
async_add_device=async_add_device_callback, async_add_device=async_add_device_callback,
connection_status=async_connection_status_callback, connection_status=async_connection_status_callback,
) )
try: try:
with async_timeout.timeout(10): with async_timeout.timeout(10):
await deconz.async_load_parameters() await deconz.initialize()
return deconz return deconz
except errors.Unauthorized: except errors.Unauthorized:
@ -234,7 +235,7 @@ async def get_gateway(
class DeconzEntityHandler: class DeconzEntityHandler:
"""Platform entity handler to help with updating disabled by.""" """Platform entity handler to help with updating disabled by."""
def __init__(self, gateway): def __init__(self, gateway) -> None:
"""Create an entity handler.""" """Create an entity handler."""
self.gateway = gateway self.gateway = gateway
self._entities = [] self._entities = []
@ -246,12 +247,12 @@ class DeconzEntityHandler:
) )
@callback @callback
def add_entity(self, entity): def add_entity(self, entity) -> None:
"""Add a new entity to handler.""" """Add a new entity to handler."""
self._entities.append(entity) self._entities.append(entity)
@callback @callback
def update_entity_registry(self, entity_registry): def update_entity_registry(self, entity_registry) -> None:
"""Update entity registry disabled by status.""" """Update entity registry disabled by status."""
for entity in self._entities: for entity in self._entities:

View File

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/deconz", "documentation": "https://www.home-assistant.io/integrations/deconz",
"requirements": [ "requirements": [
"pydeconz==64" "pydeconz==65"
], ],
"ssdp": [ "ssdp": [
{ {

View File

@ -4,7 +4,15 @@ import voluptuous as vol
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from .config_flow import get_master_gateway from .config_flow import get_master_gateway
from .const import _LOGGER, CONF_BRIDGEID, DOMAIN from .const import (
_LOGGER,
CONF_BRIDGEID,
DOMAIN,
NEW_GROUP,
NEW_LIGHT,
NEW_SCENE,
NEW_SENSOR,
)
DECONZ_SERVICES = "deconz_services" DECONZ_SERVICES = "deconz_services"
@ -105,7 +113,7 @@ async def async_configure_service(hass, data):
_LOGGER.error("Could not find the entity %s", entity_id) _LOGGER.error("Could not find the entity %s", entity_id)
return return
await gateway.api.async_put_state(field, data) await gateway.api.request("put", field, json=data)
async def async_refresh_devices_service(hass, data): async def async_refresh_devices_service(hass, data):
@ -119,10 +127,10 @@ async def async_refresh_devices_service(hass, data):
scenes = set(gateway.api.scenes.keys()) scenes = set(gateway.api.scenes.keys())
sensors = set(gateway.api.sensors.keys()) sensors = set(gateway.api.sensors.keys())
await gateway.api.async_load_parameters() await gateway.api.refresh_state()
gateway.async_add_device_callback( gateway.async_add_device_callback(
"group", NEW_GROUP,
[ [
group group
for group_id, group in gateway.api.groups.items() for group_id, group in gateway.api.groups.items()
@ -131,7 +139,7 @@ async def async_refresh_devices_service(hass, data):
) )
gateway.async_add_device_callback( gateway.async_add_device_callback(
"light", NEW_LIGHT,
[ [
light light
for light_id, light in gateway.api.lights.items() for light_id, light in gateway.api.lights.items()
@ -140,7 +148,7 @@ async def async_refresh_devices_service(hass, data):
) )
gateway.async_add_device_callback( gateway.async_add_device_callback(
"scene", NEW_SCENE,
[ [
scene scene
for scene_id, scene in gateway.api.scenes.items() for scene_id, scene in gateway.api.scenes.items()
@ -149,7 +157,7 @@ async def async_refresh_devices_service(hass, data):
) )
gateway.async_add_device_callback( gateway.async_add_device_callback(
"sensor", NEW_SENSOR,
[ [
sensor sensor
for sensor_id, sensor in gateway.api.sensors.items() for sensor_id, sensor in gateway.api.sensors.items()

View File

@ -1180,7 +1180,7 @@ pydaikin==1.6.1
pydanfossair==0.1.0 pydanfossair==0.1.0
# homeassistant.components.deconz # homeassistant.components.deconz
pydeconz==64 pydeconz==65
# homeassistant.components.delijn # homeassistant.components.delijn
pydelijn==0.5.1 pydelijn==0.5.1

View File

@ -406,7 +406,7 @@ pycoolmasternet==0.0.4
pydaikin==1.6.1 pydaikin==1.6.1
# homeassistant.components.deconz # homeassistant.components.deconz
pydeconz==64 pydeconz==65
# homeassistant.components.zwave # homeassistant.components.zwave
pydispatcher==2.0.5 pydispatcher==2.0.5

View File

@ -95,7 +95,14 @@ async def test_binary_sensors(hass):
vibration_sensor = hass.states.get("binary_sensor.vibration_sensor") vibration_sensor = hass.states.get("binary_sensor.vibration_sensor")
assert vibration_sensor.state == "on" assert vibration_sensor.state == "on"
gateway.api.sensors["1"].async_update({"state": {"presence": True}}) state_changed_event = {
"t": "event",
"e": "changed",
"r": "sensors",
"id": "1",
"state": {"presence": True},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
presence_sensor = hass.states.get("binary_sensor.presence_sensor") presence_sensor = hass.states.get("binary_sensor.presence_sensor")
@ -143,14 +150,14 @@ async def test_add_new_binary_sensor(hass):
) )
assert len(gateway.deconz_ids) == 0 assert len(gateway.deconz_ids) == 0
state_added = { state_added_event = {
"t": "event", "t": "event",
"e": "added", "e": "added",
"r": "sensors", "r": "sensors",
"id": "1", "id": "1",
"sensor": deepcopy(SENSORS["1"]), "sensor": deepcopy(SENSORS["1"]),
} }
gateway.api.async_event_handler(state_added) gateway.api.async_event_handler(state_added_event)
await hass.async_block_till_done() await hass.async_block_till_done()
assert "binary_sensor.presence_sensor" in gateway.deconz_ids assert "binary_sensor.presence_sensor" in gateway.deconz_ids

View File

@ -94,21 +94,41 @@ async def test_climate_devices(hass):
clip_thermostat = hass.states.get("climate.clip_thermostat") clip_thermostat = hass.states.get("climate.clip_thermostat")
assert clip_thermostat is None assert clip_thermostat is None
thermostat_device = gateway.api.sensors["1"] state_changed_event = {
"t": "event",
thermostat_device.async_update({"config": {"mode": "off"}}) "e": "changed",
"r": "sensors",
"id": "1",
"config": {"mode": "off"},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
thermostat = hass.states.get("climate.thermostat") thermostat = hass.states.get("climate.thermostat")
assert thermostat.state == "off" assert thermostat.state == "off"
thermostat_device.async_update({"config": {"mode": "other"}, "state": {"on": True}}) state_changed_event = {
"t": "event",
"e": "changed",
"r": "sensors",
"id": "1",
"config": {"mode": "other"},
"state": {"on": True},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
thermostat = hass.states.get("climate.thermostat") thermostat = hass.states.get("climate.thermostat")
assert thermostat.state == "heat" assert thermostat.state == "heat"
thermostat_device.async_update({"state": {"on": False}}) state_changed_event = {
"t": "event",
"e": "changed",
"r": "sensors",
"id": "1",
"state": {"on": False},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
thermostat = hass.states.get("climate.thermostat") thermostat = hass.states.get("climate.thermostat")
@ -116,9 +136,9 @@ async def test_climate_devices(hass):
# Verify service calls # Verify service calls
with patch.object( thermostat_device = gateway.api.sensors["1"]
thermostat_device, "_async_set_callback", return_value=True
) as set_callback: with patch.object(thermostat_device, "_request", return_value=True) as set_callback:
await hass.services.async_call( await hass.services.async_call(
climate.DOMAIN, climate.DOMAIN,
climate.SERVICE_SET_HVAC_MODE, climate.SERVICE_SET_HVAC_MODE,
@ -126,11 +146,11 @@ async def test_climate_devices(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/sensors/1/config", {"mode": "auto"}) set_callback.assert_called_with(
"put", "/sensors/1/config", json={"mode": "auto"}
)
with patch.object( with patch.object(thermostat_device, "_request", return_value=True) as set_callback:
thermostat_device, "_async_set_callback", return_value=True
) as set_callback:
await hass.services.async_call( await hass.services.async_call(
climate.DOMAIN, climate.DOMAIN,
climate.SERVICE_SET_HVAC_MODE, climate.SERVICE_SET_HVAC_MODE,
@ -138,29 +158,31 @@ async def test_climate_devices(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/sensors/1/config", {"mode": "heat"}) set_callback.assert_called_with(
"put", "/sensors/1/config", json={"mode": "heat"}
)
with patch.object( with patch.object(thermostat_device, "_request", return_value=True) as set_callback:
thermostat_device, "_async_set_callback", return_value=True
) as set_callback:
await hass.services.async_call( await hass.services.async_call(
climate.DOMAIN, climate.DOMAIN,
climate.SERVICE_SET_HVAC_MODE, climate.SERVICE_SET_HVAC_MODE,
{"entity_id": "climate.thermostat", "hvac_mode": "off"}, {"entity_id": "climate.thermostat", "hvac_mode": "off"},
blocking=True, blocking=True,
) )
set_callback.assert_called_with("/sensors/1/config", {"mode": "off"}) set_callback.assert_called_with(
"put", "/sensors/1/config", json={"mode": "off"}
)
with patch.object( with patch.object(thermostat_device, "_request", return_value=True) as set_callback:
thermostat_device, "_async_set_callback", return_value=True
) as set_callback:
await hass.services.async_call( await hass.services.async_call(
climate.DOMAIN, climate.DOMAIN,
climate.SERVICE_SET_TEMPERATURE, climate.SERVICE_SET_TEMPERATURE,
{"entity_id": "climate.thermostat", "temperature": 20}, {"entity_id": "climate.thermostat", "temperature": 20},
blocking=True, blocking=True,
) )
set_callback.assert_called_with("/sensors/1/config", {"heatsetpoint": 2000.0}) set_callback.assert_called_with(
"put", "/sensors/1/config", json={"heatsetpoint": 2000.0}
)
await gateway.async_reset() await gateway.async_reset()
@ -212,14 +234,14 @@ async def test_verify_state_update(hass):
thermostat = hass.states.get("climate.thermostat") thermostat = hass.states.get("climate.thermostat")
assert thermostat.state == "auto" assert thermostat.state == "auto"
state_update = { state_changed_event = {
"t": "event", "t": "event",
"e": "changed", "e": "changed",
"r": "sensors", "r": "sensors",
"id": "1", "id": "1",
"state": {"on": False}, "state": {"on": False},
} }
gateway.api.async_event_handler(state_update) gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
thermostat = hass.states.get("climate.thermostat") thermostat = hass.states.get("climate.thermostat")
@ -235,14 +257,14 @@ async def test_add_new_climate_device(hass):
) )
assert len(gateway.deconz_ids) == 0 assert len(gateway.deconz_ids) == 0
state_added = { state_added_event = {
"t": "event", "t": "event",
"e": "added", "e": "added",
"r": "sensors", "r": "sensors",
"id": "1", "id": "1",
"sensor": deepcopy(SENSORS["1"]), "sensor": deepcopy(SENSORS["1"]),
} }
gateway.api.async_event_handler(state_added) gateway.api.async_event_handler(state_added_event)
await hass.async_block_till_done() await hass.async_block_till_done()
assert "climate.thermostat" in gateway.deconz_ids assert "climate.thermostat" in gateway.deconz_ids

View File

@ -73,16 +73,23 @@ async def test_cover(hass):
level_controllable_cover = hass.states.get("cover.level_controllable_cover") level_controllable_cover = hass.states.get("cover.level_controllable_cover")
assert level_controllable_cover.state == "open" assert level_controllable_cover.state == "open"
level_controllable_cover_device = gateway.api.lights["1"] state_changed_event = {
"t": "event",
level_controllable_cover_device.async_update({"state": {"on": True}}) "e": "changed",
"r": "lights",
"id": "1",
"state": {"on": True},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
level_controllable_cover = hass.states.get("cover.level_controllable_cover") level_controllable_cover = hass.states.get("cover.level_controllable_cover")
assert level_controllable_cover.state == "closed" assert level_controllable_cover.state == "closed"
level_controllable_cover_device = gateway.api.lights["1"]
with patch.object( with patch.object(
level_controllable_cover_device, "_async_set_callback", return_value=True level_controllable_cover_device, "_request", return_value=True
) as set_callback: ) as set_callback:
await hass.services.async_call( await hass.services.async_call(
cover.DOMAIN, cover.DOMAIN,
@ -91,10 +98,10 @@ async def test_cover(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"on": False}) set_callback.assert_called_with("put", "/lights/1/state", json={"on": False})
with patch.object( with patch.object(
level_controllable_cover_device, "_async_set_callback", return_value=True level_controllable_cover_device, "_request", return_value=True
) as set_callback: ) as set_callback:
await hass.services.async_call( await hass.services.async_call(
cover.DOMAIN, cover.DOMAIN,
@ -103,10 +110,12 @@ async def test_cover(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"on": True, "bri": 255}) set_callback.assert_called_with(
"put", "/lights/1/state", json={"on": True, "bri": 255}
)
with patch.object( with patch.object(
level_controllable_cover_device, "_async_set_callback", return_value=True level_controllable_cover_device, "_request", return_value=True
) as set_callback: ) as set_callback:
await hass.services.async_call( await hass.services.async_call(
cover.DOMAIN, cover.DOMAIN,
@ -115,7 +124,7 @@ async def test_cover(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"bri_inc": 0}) set_callback.assert_called_with("put", "/lights/1/state", json={"bri_inc": 0})
await gateway.async_reset() await gateway.async_reset()

View File

@ -51,8 +51,12 @@ async def setup_deconz_integration(hass, config, options, get_state_response):
entry_id="1", entry_id="1",
) )
for resource in ("groups", "lights", "sensors"):
if resource not in get_state_response:
get_state_response[resource] = {}
with patch( with patch(
"pydeconz.DeconzSession.async_get_state", return_value=get_state_response "pydeconz.DeconzSession.request", return_value=get_state_response
), patch("pydeconz.DeconzSession.start", return_value=True): ), patch("pydeconz.DeconzSession.start", return_value=True):
await deconz.async_setup_entry(hass, config_entry) await deconz.async_setup_entry(hass, config_entry)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -172,15 +176,14 @@ async def test_reset_after_successful_setup(hass):
async def test_get_gateway(hass): async def test_get_gateway(hass):
"""Successful call.""" """Successful call."""
with patch("pydeconz.DeconzSession.async_load_parameters", return_value=True): with patch("pydeconz.DeconzSession.initialize", return_value=True):
assert await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) assert await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
async def test_get_gateway_fails_unauthorized(hass): async def test_get_gateway_fails_unauthorized(hass):
"""Failed call.""" """Failed call."""
with patch( with patch(
"pydeconz.DeconzSession.async_load_parameters", "pydeconz.DeconzSession.initialize", side_effect=pydeconz.errors.Unauthorized,
side_effect=pydeconz.errors.Unauthorized,
), pytest.raises(deconz.errors.AuthenticationRequired): ), pytest.raises(deconz.errors.AuthenticationRequired):
assert ( assert (
await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
@ -191,8 +194,7 @@ async def test_get_gateway_fails_unauthorized(hass):
async def test_get_gateway_fails_cannot_connect(hass): async def test_get_gateway_fails_cannot_connect(hass):
"""Failed call.""" """Failed call."""
with patch( with patch(
"pydeconz.DeconzSession.async_load_parameters", "pydeconz.DeconzSession.initialize", side_effect=pydeconz.errors.RequestError,
side_effect=pydeconz.errors.RequestError,
), pytest.raises(deconz.errors.CannotConnect): ), pytest.raises(deconz.errors.CannotConnect):
assert ( assert (
await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())

View File

@ -41,7 +41,7 @@ async def test_setup_entry_fails(hass):
deconz.config_flow.CONF_PORT: ENTRY1_PORT, deconz.config_flow.CONF_PORT: ENTRY1_PORT,
deconz.config_flow.CONF_API_KEY: ENTRY1_API_KEY, deconz.config_flow.CONF_API_KEY: ENTRY1_API_KEY,
} }
with patch("pydeconz.DeconzSession.async_load_parameters", side_effect=Exception): with patch("pydeconz.DeconzSession.initialize", side_effect=Exception):
await deconz.async_setup_entry(hass, entry) await deconz.async_setup_entry(hass, entry)
@ -54,7 +54,7 @@ async def test_setup_entry_no_available_bridge(hass):
deconz.config_flow.CONF_API_KEY: ENTRY1_API_KEY, deconz.config_flow.CONF_API_KEY: ENTRY1_API_KEY,
} }
with patch( with patch(
"pydeconz.DeconzSession.async_load_parameters", side_effect=asyncio.TimeoutError "pydeconz.DeconzSession.initialize", side_effect=asyncio.TimeoutError
), pytest.raises(ConfigEntryNotReady): ), pytest.raises(ConfigEntryNotReady):
await deconz.async_setup_entry(hass, entry) await deconz.async_setup_entry(hass, entry)

View File

@ -117,17 +117,22 @@ async def test_lights_and_groups(hass):
empty_group = hass.states.get("light.empty_group") empty_group = hass.states.get("light.empty_group")
assert empty_group is None assert empty_group is None
rgb_light_device = gateway.api.lights["1"] state_changed_event = {
"t": "event",
rgb_light_device.async_update({"state": {"on": False}}) "e": "changed",
"r": "lights",
"id": "1",
"state": {"on": False},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
rgb_light = hass.states.get("light.rgb_light") rgb_light = hass.states.get("light.rgb_light")
assert rgb_light.state == "off" assert rgb_light.state == "off"
with patch.object( rgb_light_device = gateway.api.lights["1"]
rgb_light_device, "_async_set_callback", return_value=True
) as set_callback: with patch.object(rgb_light_device, "_request", return_value=True) as set_callback:
await hass.services.async_call( await hass.services.async_call(
light.DOMAIN, light.DOMAIN,
light.SERVICE_TURN_ON, light.SERVICE_TURN_ON,
@ -143,8 +148,9 @@ async def test_lights_and_groups(hass):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with( set_callback.assert_called_with(
"put",
"/lights/1/state", "/lights/1/state",
{ json={
"ct": 2500, "ct": 2500,
"bri": 200, "bri": 200,
"transitiontime": 50, "transitiontime": 50,
@ -153,9 +159,7 @@ async def test_lights_and_groups(hass):
}, },
) )
with patch.object( with patch.object(rgb_light_device, "_request", return_value=True) as set_callback:
rgb_light_device, "_async_set_callback", return_value=True
) as set_callback:
await hass.services.async_call( await hass.services.async_call(
light.DOMAIN, light.DOMAIN,
light.SERVICE_TURN_ON, light.SERVICE_TURN_ON,
@ -169,13 +173,12 @@ async def test_lights_and_groups(hass):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with( set_callback.assert_called_with(
"put",
"/lights/1/state", "/lights/1/state",
{"xy": (0.411, 0.351), "alert": "lselect", "effect": "none"}, json={"xy": (0.411, 0.351), "alert": "lselect", "effect": "none"},
) )
with patch.object( with patch.object(rgb_light_device, "_request", return_value=True) as set_callback:
rgb_light_device, "_async_set_callback", return_value=True
) as set_callback:
await hass.services.async_call( await hass.services.async_call(
light.DOMAIN, light.DOMAIN,
light.SERVICE_TURN_OFF, light.SERVICE_TURN_OFF,
@ -184,12 +187,12 @@ async def test_lights_and_groups(hass):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with( set_callback.assert_called_with(
"/lights/1/state", {"bri": 0, "transitiontime": 50, "alert": "select"} "put",
"/lights/1/state",
json={"bri": 0, "transitiontime": 50, "alert": "select"},
) )
with patch.object( with patch.object(rgb_light_device, "_request", return_value=True) as set_callback:
rgb_light_device, "_async_set_callback", return_value=True
) as set_callback:
await hass.services.async_call( await hass.services.async_call(
light.DOMAIN, light.DOMAIN,
light.SERVICE_TURN_OFF, light.SERVICE_TURN_OFF,
@ -197,7 +200,9 @@ async def test_lights_and_groups(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"alert": "lselect"}) set_callback.assert_called_with(
"put", "/lights/1/state", json={"alert": "lselect"}
)
await gateway.async_reset() await gateway.async_reset()

View File

@ -60,14 +60,12 @@ async def test_scenes(hass):
group_scene = gateway.api.groups["1"].scenes["1"] group_scene = gateway.api.groups["1"].scenes["1"]
with patch.object( with patch.object(group_scene, "_request", return_value=True) as set_callback:
group_scene, "_async_set_state_callback", return_value=True
) as set_callback:
await hass.services.async_call( await hass.services.async_call(
"scene", "turn_on", {"entity_id": "scene.light_group_scene"}, blocking=True "scene", "turn_on", {"entity_id": "scene.light_group_scene"}, blocking=True
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/groups/1/scenes/1/recall", {}) set_callback.assert_called_with("put", "/groups/1/scenes/1/recall", json={})
await gateway.async_reset() await gateway.async_reset()

View File

@ -143,8 +143,23 @@ async def test_sensors(hass):
consumption_sensor = hass.states.get("sensor.consumption_sensor") consumption_sensor = hass.states.get("sensor.consumption_sensor")
assert consumption_sensor.state == "0.002" assert consumption_sensor.state == "0.002"
gateway.api.sensors["1"].async_update({"state": {"lightlevel": 2000}}) state_changed_event = {
gateway.api.sensors["4"].async_update({"config": {"battery": 75}}) "t": "event",
"e": "changed",
"r": "sensors",
"id": "1",
"state": {"lightlevel": 2000},
}
gateway.api.async_event_handler(state_changed_event)
state_changed_event = {
"t": "event",
"e": "changed",
"r": "sensors",
"id": "4",
"config": {"battery": 75},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
light_level_sensor = hass.states.get("sensor.light_level_sensor") light_level_sensor = hass.states.get("sensor.light_level_sensor")
@ -219,14 +234,14 @@ async def test_add_new_sensor(hass):
) )
assert len(gateway.deconz_ids) == 0 assert len(gateway.deconz_ids) == 0
state_added = { state_added_event = {
"t": "event", "t": "event",
"e": "added", "e": "added",
"r": "sensors", "r": "sensors",
"id": "1", "id": "1",
"sensor": deepcopy(SENSORS["1"]), "sensor": deepcopy(SENSORS["1"]),
} }
gateway.api.async_event_handler(state_added) gateway.api.async_event_handler(state_added_event)
await hass.async_block_till_done() await hass.async_block_till_done()
assert "sensor.light_level_sensor" in gateway.deconz_ids assert "sensor.light_level_sensor" in gateway.deconz_ids

View File

@ -104,14 +104,14 @@ async def test_configure_service_with_field(hass):
deconz.services.SERVICE_DATA: {"on": True, "attr1": 10, "attr2": 20}, deconz.services.SERVICE_DATA: {"on": True, "attr1": 10, "attr2": 20},
} }
with patch( with patch("pydeconz.DeconzSession.request", return_value=Mock(True)) as put_state:
"pydeconz.DeconzSession.async_put_state", return_value=Mock(True)
) as put_state:
await hass.services.async_call( await hass.services.async_call(
deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data
) )
await hass.async_block_till_done() await hass.async_block_till_done()
put_state.assert_called_with("/light/2", {"on": True, "attr1": 10, "attr2": 20}) put_state.assert_called_with(
"put", "/light/2", json={"on": True, "attr1": 10, "attr2": 20}
)
async def test_configure_service_with_entity(hass): async def test_configure_service_with_entity(hass):
@ -127,14 +127,14 @@ async def test_configure_service_with_entity(hass):
deconz.services.SERVICE_DATA: {"on": True, "attr1": 10, "attr2": 20}, deconz.services.SERVICE_DATA: {"on": True, "attr1": 10, "attr2": 20},
} }
with patch( with patch("pydeconz.DeconzSession.request", return_value=Mock(True)) as put_state:
"pydeconz.DeconzSession.async_put_state", return_value=Mock(True)
) as put_state:
await hass.services.async_call( await hass.services.async_call(
deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data
) )
await hass.async_block_till_done() await hass.async_block_till_done()
put_state.assert_called_with("/light/1", {"on": True, "attr1": 10, "attr2": 20}) put_state.assert_called_with(
"put", "/light/1", json={"on": True, "attr1": 10, "attr2": 20}
)
async def test_configure_service_with_entity_and_field(hass): async def test_configure_service_with_entity_and_field(hass):
@ -151,15 +151,13 @@ async def test_configure_service_with_entity_and_field(hass):
deconz.services.SERVICE_DATA: {"on": True, "attr1": 10, "attr2": 20}, deconz.services.SERVICE_DATA: {"on": True, "attr1": 10, "attr2": 20},
} }
with patch( with patch("pydeconz.DeconzSession.request", return_value=Mock(True)) as put_state:
"pydeconz.DeconzSession.async_put_state", return_value=Mock(True)
) as put_state:
await hass.services.async_call( await hass.services.async_call(
deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data
) )
await hass.async_block_till_done() await hass.async_block_till_done()
put_state.assert_called_with( put_state.assert_called_with(
"/light/1/state", {"on": True, "attr1": 10, "attr2": 20} "put", "/light/1/state", json={"on": True, "attr1": 10, "attr2": 20}
) )
@ -191,9 +189,7 @@ async def test_configure_service_with_faulty_entity(hass):
deconz.services.SERVICE_DATA: {}, deconz.services.SERVICE_DATA: {},
} }
with patch( with patch("pydeconz.DeconzSession.request", return_value=Mock(True)) as put_state:
"pydeconz.DeconzSession.async_put_state", return_value=Mock(True)
) as put_state:
await hass.services.async_call( await hass.services.async_call(
deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data deconz.DOMAIN, deconz.services.SERVICE_CONFIGURE_DEVICE, service_data=data
) )
@ -211,7 +207,7 @@ async def test_service_refresh_devices(hass):
data = {deconz.CONF_BRIDGEID: BRIDGEID} data = {deconz.CONF_BRIDGEID: BRIDGEID}
with patch( with patch(
"pydeconz.DeconzSession.async_get_state", "pydeconz.DeconzSession.request",
return_value={"groups": GROUP, "lights": LIGHT, "sensors": SENSOR}, return_value={"groups": GROUP, "lights": LIGHT, "sensors": SENSOR},
): ):
await hass.services.async_call( await hass.services.async_call(

View File

@ -85,11 +85,22 @@ async def test_switches(hass):
warning_device = hass.states.get("switch.warning_device") warning_device = hass.states.get("switch.warning_device")
assert warning_device.state == "on" assert warning_device.state == "on"
on_off_switch_device = gateway.api.lights["1"] state_changed_event = {
warning_device_device = gateway.api.lights["3"] "t": "event",
"e": "changed",
on_off_switch_device.async_update({"state": {"on": False}}) "r": "lights",
warning_device_device.async_update({"state": {"alert": None}}) "id": "1",
"state": {"on": False},
}
gateway.api.async_event_handler(state_changed_event)
state_changed_event = {
"t": "event",
"e": "changed",
"r": "lights",
"id": "3",
"state": {"alert": None},
}
gateway.api.async_event_handler(state_changed_event)
await hass.async_block_till_done() await hass.async_block_till_done()
on_off_switch = hass.states.get("switch.on_off_switch") on_off_switch = hass.states.get("switch.on_off_switch")
@ -98,8 +109,10 @@ async def test_switches(hass):
warning_device = hass.states.get("switch.warning_device") warning_device = hass.states.get("switch.warning_device")
assert warning_device.state == "off" assert warning_device.state == "off"
on_off_switch_device = gateway.api.lights["1"]
with patch.object( with patch.object(
on_off_switch_device, "_async_set_callback", return_value=True on_off_switch_device, "_request", return_value=True
) as set_callback: ) as set_callback:
await hass.services.async_call( await hass.services.async_call(
switch.DOMAIN, switch.DOMAIN,
@ -108,10 +121,10 @@ async def test_switches(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"on": True}) set_callback.assert_called_with("put", "/lights/1/state", json={"on": True})
with patch.object( with patch.object(
on_off_switch_device, "_async_set_callback", return_value=True on_off_switch_device, "_request", return_value=True
) as set_callback: ) as set_callback:
await hass.services.async_call( await hass.services.async_call(
switch.DOMAIN, switch.DOMAIN,
@ -120,10 +133,12 @@ async def test_switches(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"on": False}) set_callback.assert_called_with("put", "/lights/1/state", json={"on": False})
warning_device_device = gateway.api.lights["3"]
with patch.object( with patch.object(
warning_device_device, "_async_set_callback", return_value=True warning_device_device, "_request", return_value=True
) as set_callback: ) as set_callback:
await hass.services.async_call( await hass.services.async_call(
switch.DOMAIN, switch.DOMAIN,
@ -132,10 +147,12 @@ async def test_switches(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/3/state", {"alert": "lselect"}) set_callback.assert_called_with(
"put", "/lights/3/state", json={"alert": "lselect"}
)
with patch.object( with patch.object(
warning_device_device, "_async_set_callback", return_value=True warning_device_device, "_request", return_value=True
) as set_callback: ) as set_callback:
await hass.services.async_call( await hass.services.async_call(
switch.DOMAIN, switch.DOMAIN,
@ -144,7 +161,9 @@ async def test_switches(hass):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/3/state", {"alert": "none"}) set_callback.assert_called_with(
"put", "/lights/3/state", json={"alert": "none"}
)
await gateway.async_reset() await gateway.async_reset()