Skip to content

Commit 4b25d04

Browse files
authored
Refactor Velux integration to use runtime_data (#155207)
1 parent 4e3eb44 commit 4b25d04

File tree

8 files changed

+48
-81
lines changed

8 files changed

+48
-81
lines changed

homeassistant/components/velux/__init__.py

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,38 @@
88

99
from .const import DOMAIN, LOGGER, PLATFORMS
1010

11+
type VeluxConfigEntry = ConfigEntry[PyVLX]
12+
1113

1214
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
1315
"""Set up the velux component."""
14-
module = VeluxModule(hass, entry.data)
15-
try:
16-
module.setup()
17-
await module.async_start()
16+
host = entry.data[CONF_HOST]
17+
password = entry.data[CONF_PASSWORD]
18+
pyvlx = PyVLX(host=host, password=password)
1819

20+
LOGGER.debug("Velux interface started")
21+
try:
22+
await pyvlx.load_scenes()
23+
await pyvlx.load_nodes()
1924
except PyVLXException as ex:
2025
LOGGER.exception("Can't connect to velux interface: %s", ex)
2126
return False
2227

23-
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = module
28+
entry.runtime_data = pyvlx
29+
30+
async def on_hass_stop(event):
31+
"""Close connection when hass stops."""
32+
LOGGER.debug("Velux interface terminated")
33+
await pyvlx.disconnect()
34+
35+
async def async_reboot_gateway(service_call: ServiceCall) -> None:
36+
await pyvlx.reboot_gateway()
37+
38+
entry.async_on_unload(
39+
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, on_hass_stop)
40+
)
41+
42+
hass.services.async_register(DOMAIN, "reboot_gateway", async_reboot_gateway)
2443

2544
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
2645

@@ -30,39 +49,3 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
3049
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
3150
"""Unload a config entry."""
3251
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
33-
34-
35-
class VeluxModule:
36-
"""Abstraction for velux component."""
37-
38-
def __init__(self, hass, domain_config):
39-
"""Initialize for velux component."""
40-
self.pyvlx = None
41-
self._hass = hass
42-
self._domain_config = domain_config
43-
44-
def setup(self):
45-
"""Velux component setup."""
46-
47-
async def on_hass_stop(event):
48-
"""Close connection when hass stops."""
49-
LOGGER.debug("Velux interface terminated")
50-
await self.pyvlx.disconnect()
51-
52-
async def async_reboot_gateway(service_call: ServiceCall) -> None:
53-
await self.pyvlx.reboot_gateway()
54-
55-
self._hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, on_hass_stop)
56-
host = self._domain_config.get(CONF_HOST)
57-
password = self._domain_config.get(CONF_PASSWORD)
58-
self.pyvlx = PyVLX(host=host, password=password)
59-
60-
self._hass.services.async_register(
61-
DOMAIN, "reboot_gateway", async_reboot_gateway
62-
)
63-
64-
async def async_start(self):
65-
"""Start velux component."""
66-
LOGGER.debug("Velux interface started")
67-
await self.pyvlx.load_scenes()
68-
await self.pyvlx.load_nodes()

homeassistant/components/velux/binary_sensor.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
BinarySensorDeviceClass,
1212
BinarySensorEntity,
1313
)
14-
from homeassistant.config_entries import ConfigEntry
1514
from homeassistant.core import HomeAssistant
1615
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
1716

18-
from .const import DOMAIN, LOGGER
17+
from . import VeluxConfigEntry
18+
from .const import LOGGER
1919
from .entity import VeluxEntity
2020

2121
PARALLEL_UPDATES = 1
@@ -24,15 +24,15 @@
2424

2525
async def async_setup_entry(
2626
hass: HomeAssistant,
27-
config: ConfigEntry,
27+
config: VeluxConfigEntry,
2828
async_add_entities: AddConfigEntryEntitiesCallback,
2929
) -> None:
3030
"""Set up rain sensor(s) for Velux platform."""
31-
module = hass.data[DOMAIN][config.entry_id]
31+
pyvlx = config.runtime_data
3232

3333
async_add_entities(
3434
VeluxRainSensor(node, config.entry_id)
35-
for node in module.pyvlx.nodes
35+
for node in pyvlx.nodes
3636
if isinstance(node, Window) and node.rain_sensor
3737
)
3838

homeassistant/components/velux/cover.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,25 @@
2121
CoverEntity,
2222
CoverEntityFeature,
2323
)
24-
from homeassistant.config_entries import ConfigEntry
2524
from homeassistant.core import HomeAssistant
2625
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
2726

28-
from .const import DOMAIN
27+
from . import VeluxConfigEntry
2928
from .entity import VeluxEntity
3029

3130
PARALLEL_UPDATES = 1
3231

3332

3433
async def async_setup_entry(
3534
hass: HomeAssistant,
36-
config: ConfigEntry,
35+
config: VeluxConfigEntry,
3736
async_add_entities: AddConfigEntryEntitiesCallback,
3837
) -> None:
3938
"""Set up cover(s) for Velux platform."""
40-
module = hass.data[DOMAIN][config.entry_id]
39+
pyvlx = config.runtime_data
4140
async_add_entities(
4241
VeluxCover(node, config.entry_id)
43-
for node in module.pyvlx.nodes
42+
for node in pyvlx.nodes
4443
if isinstance(node, OpeningDevice)
4544
)
4645

homeassistant/components/velux/light.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,25 @@
77
from pyvlx import Intensity, LighteningDevice
88

99
from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity
10-
from homeassistant.config_entries import ConfigEntry
1110
from homeassistant.core import HomeAssistant
1211
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
1312

14-
from .const import DOMAIN
13+
from . import VeluxConfigEntry
1514
from .entity import VeluxEntity
1615

1716
PARALLEL_UPDATES = 1
1817

1918

2019
async def async_setup_entry(
2120
hass: HomeAssistant,
22-
config: ConfigEntry,
21+
config: VeluxConfigEntry,
2322
async_add_entities: AddConfigEntryEntitiesCallback,
2423
) -> None:
2524
"""Set up light(s) for Velux platform."""
26-
module = hass.data[DOMAIN][config.entry_id]
27-
25+
pyvlx = config.runtime_data
2826
async_add_entities(
2927
VeluxLight(node, config.entry_id)
30-
for node in module.pyvlx.nodes
28+
for node in pyvlx.nodes
3129
if isinstance(node, LighteningDevice)
3230
)
3331

homeassistant/components/velux/scene.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,23 @@
55
from typing import Any
66

77
from homeassistant.components.scene import Scene
8-
from homeassistant.config_entries import ConfigEntry
98
from homeassistant.core import HomeAssistant
109
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
1110

12-
from .const import DOMAIN
11+
from . import VeluxConfigEntry
1312

1413
PARALLEL_UPDATES = 1
1514

1615

1716
async def async_setup_entry(
1817
hass: HomeAssistant,
19-
config: ConfigEntry,
18+
config: VeluxConfigEntry,
2019
async_add_entities: AddConfigEntryEntitiesCallback,
2120
) -> None:
2221
"""Set up the scenes for Velux platform."""
23-
module = hass.data[DOMAIN][config.entry_id]
22+
pyvlx = config.runtime_data
2423

25-
entities = [VeluxScene(scene) for scene in module.pyvlx.scenes]
24+
entities = [VeluxScene(scene) for scene in pyvlx.scenes]
2625
async_add_entities(entities)
2726

2827

tests/components/velux/conftest.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,16 @@ def mock_window() -> AsyncMock:
7979

8080

8181
@pytest.fixture
82-
def mock_pyvlx(mock_window: MagicMock) -> MagicMock:
83-
"""Create the library mock."""
82+
def mock_pyvlx(mock_window: MagicMock) -> Generator[MagicMock]:
83+
"""Create the library mock and patch PyVLX."""
8484
pyvlx = MagicMock()
8585
pyvlx.nodes = [mock_window]
8686
pyvlx.load_scenes = AsyncMock()
8787
pyvlx.load_nodes = AsyncMock()
8888
pyvlx.disconnect = AsyncMock()
89-
return pyvlx
9089

91-
92-
@pytest.fixture
93-
def mock_module(mock_pyvlx: MagicMock) -> Generator[AsyncMock]:
94-
"""Create the Velux module mock."""
95-
with (
96-
patch(
97-
"homeassistant.components.velux.VeluxModule",
98-
autospec=True,
99-
) as mock_velux,
100-
):
101-
module = mock_velux.return_value
102-
module.pyvlx = mock_pyvlx
103-
yield module
90+
with patch("homeassistant.components.velux.PyVLX", return_value=pyvlx):
91+
yield pyvlx
10492

10593

10694
@pytest.fixture

tests/components/velux/test_binary_sensor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717

1818
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
19-
@pytest.mark.usefixtures("mock_module")
19+
@pytest.mark.usefixtures("mock_pyvlx")
2020
async def test_rain_sensor_state(
2121
hass: HomeAssistant,
2222
mock_window: MagicMock,
@@ -62,7 +62,7 @@ async def test_rain_sensor_state(
6262

6363

6464
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
65-
@pytest.mark.usefixtures("mock_module")
65+
@pytest.mark.usefixtures("mock_pyvlx")
6666
async def test_rain_sensor_device_association(
6767
hass: HomeAssistant,
6868
mock_window: MagicMock,

tests/components/velux/test_cover.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from tests.common import MockConfigEntry
1414

1515

16-
@pytest.mark.usefixtures("mock_module")
16+
@pytest.mark.usefixtures("mock_pyvlx")
1717
async def test_cover_closed(
1818
hass: HomeAssistant,
1919
mock_window: AsyncMock,

0 commit comments

Comments
 (0)