Skip to content

Commit 59cd24f

Browse files
authored
Add dynamic devices to Homee (home-assistant#151934)
1 parent 82b9fea commit 59cd24f

File tree

20 files changed

+1980
-123
lines changed

20 files changed

+1980
-123
lines changed

homeassistant/components/homee/alarm_control_panel.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from dataclasses import dataclass
44

55
from pyHomee.const import AttributeChangedBy, AttributeType
6-
from pyHomee.model import HomeeAttribute
6+
from pyHomee.model import HomeeAttribute, HomeeNode
77

88
from homeassistant.components.alarm_control_panel import (
99
AlarmControlPanelEntity,
@@ -17,7 +17,7 @@
1717

1818
from . import DOMAIN, HomeeConfigEntry
1919
from .entity import HomeeEntity
20-
from .helpers import get_name_for_enum
20+
from .helpers import get_name_for_enum, setup_homee_platform
2121

2222
PARALLEL_UPDATES = 0
2323

@@ -60,21 +60,32 @@ def get_supported_features(
6060
return supported_features
6161

6262

63-
async def async_setup_entry(
64-
hass: HomeAssistant,
63+
async def add_alarm_control_panel_entities(
6564
config_entry: HomeeConfigEntry,
6665
async_add_entities: AddConfigEntryEntitiesCallback,
66+
nodes: list[HomeeNode],
6767
) -> None:
68-
"""Add the Homee platform for the alarm control panel component."""
69-
68+
"""Add homee alarm control panel entities."""
7069
async_add_entities(
7170
HomeeAlarmPanel(attribute, config_entry, ALARM_DESCRIPTIONS[attribute.type])
72-
for node in config_entry.runtime_data.nodes
71+
for node in nodes
7372
for attribute in node.attributes
7473
if attribute.type in ALARM_DESCRIPTIONS and attribute.editable
7574
)
7675

7776

77+
async def async_setup_entry(
78+
hass: HomeAssistant,
79+
config_entry: HomeeConfigEntry,
80+
async_add_entities: AddConfigEntryEntitiesCallback,
81+
) -> None:
82+
"""Add the homee platform for the alarm control panel component."""
83+
84+
await setup_homee_platform(
85+
add_alarm_control_panel_entities, async_add_entities, config_entry
86+
)
87+
88+
7889
class HomeeAlarmPanel(HomeeEntity, AlarmControlPanelEntity):
7990
"""Representation of a Homee alarm control panel."""
8091

homeassistant/components/homee/binary_sensor.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""The Homee binary sensor platform."""
22

33
from pyHomee.const import AttributeType
4-
from pyHomee.model import HomeeAttribute
4+
from pyHomee.model import HomeeAttribute, HomeeNode
55

66
from homeassistant.components.binary_sensor import (
77
BinarySensorDeviceClass,
@@ -14,6 +14,7 @@
1414

1515
from . import HomeeConfigEntry
1616
from .entity import HomeeEntity
17+
from .helpers import setup_homee_platform
1718

1819
PARALLEL_UPDATES = 0
1920

@@ -152,23 +153,34 @@
152153
}
153154

154155

155-
async def async_setup_entry(
156-
hass: HomeAssistant,
156+
async def add_binary_sensor_entities(
157157
config_entry: HomeeConfigEntry,
158-
async_add_devices: AddConfigEntryEntitiesCallback,
158+
async_add_entities: AddConfigEntryEntitiesCallback,
159+
nodes: list[HomeeNode],
159160
) -> None:
160-
"""Add the Homee platform for the binary sensor component."""
161-
162-
async_add_devices(
161+
"""Add homee binary sensor entities."""
162+
async_add_entities(
163163
HomeeBinarySensor(
164164
attribute, config_entry, BINARY_SENSOR_DESCRIPTIONS[attribute.type]
165165
)
166-
for node in config_entry.runtime_data.nodes
166+
for node in nodes
167167
for attribute in node.attributes
168168
if attribute.type in BINARY_SENSOR_DESCRIPTIONS and not attribute.editable
169169
)
170170

171171

172+
async def async_setup_entry(
173+
hass: HomeAssistant,
174+
config_entry: HomeeConfigEntry,
175+
async_add_entities: AddConfigEntryEntitiesCallback,
176+
) -> None:
177+
"""Add the homee platform for the binary sensor component."""
178+
179+
await setup_homee_platform(
180+
add_binary_sensor_entities, async_add_entities, config_entry
181+
)
182+
183+
172184
class HomeeBinarySensor(HomeeEntity, BinarySensorEntity):
173185
"""Representation of a Homee binary sensor."""
174186

homeassistant/components/homee/button.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""The homee button platform."""
22

33
from pyHomee.const import AttributeType
4-
from pyHomee.model import HomeeAttribute
4+
from pyHomee.model import HomeeAttribute, HomeeNode
55

66
from homeassistant.components.button import (
77
ButtonDeviceClass,
@@ -14,6 +14,7 @@
1414

1515
from . import HomeeConfigEntry
1616
from .entity import HomeeEntity
17+
from .helpers import setup_homee_platform
1718

1819
PARALLEL_UPDATES = 0
1920

@@ -39,21 +40,30 @@
3940
}
4041

4142

42-
async def async_setup_entry(
43-
hass: HomeAssistant,
43+
async def add_button_entities(
4444
config_entry: HomeeConfigEntry,
4545
async_add_entities: AddConfigEntryEntitiesCallback,
46+
nodes: list[HomeeNode],
4647
) -> None:
47-
"""Add the Homee platform for the button component."""
48-
48+
"""Add homee button entities."""
4949
async_add_entities(
5050
HomeeButton(attribute, config_entry, BUTTON_DESCRIPTIONS[attribute.type])
51-
for node in config_entry.runtime_data.nodes
51+
for node in nodes
5252
for attribute in node.attributes
5353
if attribute.type in BUTTON_DESCRIPTIONS and attribute.editable
5454
)
5555

5656

57+
async def async_setup_entry(
58+
hass: HomeAssistant,
59+
config_entry: HomeeConfigEntry,
60+
async_add_entities: AddConfigEntryEntitiesCallback,
61+
) -> None:
62+
"""Add the homee platform for the button component."""
63+
64+
await setup_homee_platform(add_button_entities, async_add_entities, config_entry)
65+
66+
5767
class HomeeButton(HomeeEntity, ButtonEntity):
5868
"""Representation of a Homee button."""
5969

homeassistant/components/homee/climate.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from . import HomeeConfigEntry
2222
from .const import CLIMATE_PROFILES, DOMAIN, HOMEE_UNIT_TO_HA_UNIT, PRESET_MANUAL
2323
from .entity import HomeeNodeEntity
24+
from .helpers import setup_homee_platform
2425

2526
PARALLEL_UPDATES = 0
2627

@@ -31,18 +32,27 @@
3132
}
3233

3334

35+
async def add_climate_entities(
36+
config_entry: HomeeConfigEntry,
37+
async_add_entities: AddConfigEntryEntitiesCallback,
38+
nodes: list[HomeeNode],
39+
) -> None:
40+
"""Add homee climate entities."""
41+
async_add_entities(
42+
HomeeClimate(node, config_entry)
43+
for node in nodes
44+
if node.profile in CLIMATE_PROFILES
45+
)
46+
47+
3448
async def async_setup_entry(
3549
hass: HomeAssistant,
3650
config_entry: HomeeConfigEntry,
37-
async_add_devices: AddConfigEntryEntitiesCallback,
51+
async_add_entities: AddConfigEntryEntitiesCallback,
3852
) -> None:
3953
"""Add the Homee platform for the climate component."""
4054

41-
async_add_devices(
42-
HomeeClimate(node, config_entry)
43-
for node in config_entry.runtime_data.nodes
44-
if node.profile in CLIMATE_PROFILES
45-
)
55+
await setup_homee_platform(add_climate_entities, async_add_entities, config_entry)
4656

4757

4858
class HomeeClimate(HomeeNodeEntity, ClimateEntity):

homeassistant/components/homee/cover.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from . import HomeeConfigEntry
2020
from .entity import HomeeNodeEntity
21+
from .helpers import setup_homee_platform
2122

2223
_LOGGER = logging.getLogger(__name__)
2324

@@ -77,18 +78,25 @@ def get_device_class(node: HomeeNode) -> CoverDeviceClass | None:
7778
return COVER_DEVICE_PROFILES.get(node.profile)
7879

7980

81+
async def add_cover_entities(
82+
config_entry: HomeeConfigEntry,
83+
async_add_entities: AddConfigEntryEntitiesCallback,
84+
nodes: list[HomeeNode],
85+
) -> None:
86+
"""Add homee cover entities."""
87+
async_add_entities(
88+
HomeeCover(node, config_entry) for node in nodes if is_cover_node(node)
89+
)
90+
91+
8092
async def async_setup_entry(
8193
hass: HomeAssistant,
8294
config_entry: HomeeConfigEntry,
83-
async_add_devices: AddConfigEntryEntitiesCallback,
95+
async_add_entities: AddConfigEntryEntitiesCallback,
8496
) -> None:
8597
"""Add the homee platform for the cover integration."""
8698

87-
async_add_devices(
88-
HomeeCover(node, config_entry)
89-
for node in config_entry.runtime_data.nodes
90-
if is_cover_node(node)
91-
)
99+
await setup_homee_platform(add_cover_entities, async_add_entities, config_entry)
92100

93101

94102
def is_cover_node(node: HomeeNode) -> bool:

homeassistant/components/homee/event.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""The homee event platform."""
22

33
from pyHomee.const import AttributeType, NodeProfile
4-
from pyHomee.model import HomeeAttribute
4+
from pyHomee.model import HomeeAttribute, HomeeNode
55

66
from homeassistant.components.event import (
77
EventDeviceClass,
@@ -13,6 +13,7 @@
1313

1414
from . import HomeeConfigEntry
1515
from .entity import HomeeEntity
16+
from .helpers import setup_homee_platform
1617

1718
PARALLEL_UPDATES = 0
1819

@@ -49,23 +50,32 @@
4950
}
5051

5152

52-
async def async_setup_entry(
53-
hass: HomeAssistant,
53+
async def add_event_entities(
5454
config_entry: HomeeConfigEntry,
5555
async_add_entities: AddConfigEntryEntitiesCallback,
56+
nodes: list[HomeeNode],
5657
) -> None:
57-
"""Add event entities for homee."""
58-
58+
"""Add homee event entities."""
5959
async_add_entities(
6060
HomeeEvent(attribute, config_entry, EVENT_DESCRIPTIONS[attribute.type])
61-
for node in config_entry.runtime_data.nodes
61+
for node in nodes
6262
for attribute in node.attributes
6363
if attribute.type in EVENT_DESCRIPTIONS
6464
and node.profile in REMOTE_PROFILES
6565
and not attribute.editable
6666
)
6767

6868

69+
async def async_setup_entry(
70+
hass: HomeAssistant,
71+
config_entry: HomeeConfigEntry,
72+
async_add_entities: AddConfigEntryEntitiesCallback,
73+
) -> None:
74+
"""Add event entities for homee."""
75+
76+
await setup_homee_platform(add_event_entities, async_add_entities, config_entry)
77+
78+
6979
class HomeeEvent(HomeeEntity, EventEntity):
7080
"""Representation of a homee event."""
7181

homeassistant/components/homee/fan.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,32 @@
1919
from . import HomeeConfigEntry
2020
from .const import DOMAIN, PRESET_AUTO, PRESET_MANUAL, PRESET_SUMMER
2121
from .entity import HomeeNodeEntity
22+
from .helpers import setup_homee_platform
2223

2324
PARALLEL_UPDATES = 0
2425

2526

27+
async def add_fan_entities(
28+
config_entry: HomeeConfigEntry,
29+
async_add_entities: AddConfigEntryEntitiesCallback,
30+
nodes: list[HomeeNode],
31+
) -> None:
32+
"""Add homee fan entities."""
33+
async_add_entities(
34+
HomeeFan(node, config_entry)
35+
for node in nodes
36+
if node.profile == NodeProfile.VENTILATION_CONTROL
37+
)
38+
39+
2640
async def async_setup_entry(
2741
hass: HomeAssistant,
2842
config_entry: HomeeConfigEntry,
29-
async_add_devices: AddConfigEntryEntitiesCallback,
43+
async_add_entities: AddConfigEntryEntitiesCallback,
3044
) -> None:
3145
"""Set up the Homee fan platform."""
3246

33-
async_add_devices(
34-
HomeeFan(node, config_entry)
35-
for node in config_entry.runtime_data.nodes
36-
if node.profile == NodeProfile.VENTILATION_CONTROL
37-
)
47+
await setup_homee_platform(add_fan_entities, async_add_entities, config_entry)
3848

3949

4050
class HomeeFan(HomeeNodeEntity, FanEntity):

homeassistant/components/homee/helpers.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
11
"""Helper functions for the homee custom component."""
22

3+
from collections.abc import Callable, Coroutine
34
from enum import IntEnum
45
import logging
6+
from typing import Any
7+
8+
from pyHomee.model import HomeeNode
9+
10+
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
11+
12+
from . import HomeeConfigEntry
513

614
_LOGGER = logging.getLogger(__name__)
715

816

17+
async def setup_homee_platform(
18+
add_platform_entities: Callable[
19+
[HomeeConfigEntry, AddConfigEntryEntitiesCallback, list[HomeeNode]],
20+
Coroutine[Any, Any, None],
21+
],
22+
async_add_entities: AddConfigEntryEntitiesCallback,
23+
config_entry: HomeeConfigEntry,
24+
) -> None:
25+
"""Set up a homee platform."""
26+
await add_platform_entities(
27+
config_entry, async_add_entities, config_entry.runtime_data.nodes
28+
)
29+
30+
async def add_device(node: HomeeNode, add: bool) -> None:
31+
"""Dynamically add entities."""
32+
if add:
33+
await add_platform_entities(config_entry, async_add_entities, [node])
34+
35+
config_entry.async_on_unload(
36+
config_entry.runtime_data.add_nodes_listener(add_device)
37+
)
38+
39+
940
def get_name_for_enum(att_class: type[IntEnum], att_id: int) -> str | None:
1041
"""Return the enum item name for a given integer."""
1142
try:

0 commit comments

Comments
 (0)