Streamline naming in deCONZ integration (#111977)
This commit is contained in:
parent
e20cc4f8b9
commit
506240be10
24 changed files with 325 additions and 342 deletions
|
@ -7,7 +7,7 @@ from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
|||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
|
||||
from .config_flow import get_master_gateway
|
||||
from .config_flow import get_master_hub
|
||||
from .const import CONF_MASTER_GATEWAY, DOMAIN, PLATFORMS
|
||||
from .deconz_event import async_setup_events, async_unload_events
|
||||
from .errors import AuthenticationRequired, CannotConnect
|
||||
|
@ -24,7 +24,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
hass.data.setdefault(DOMAIN, {})
|
||||
|
||||
if not config_entry.options:
|
||||
await async_update_master_gateway(hass, config_entry)
|
||||
await async_update_master_hub(hass, config_entry)
|
||||
|
||||
try:
|
||||
api = await get_deconz_api(hass, config_entry)
|
||||
|
@ -36,20 +36,18 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
if not hass.data[DOMAIN]:
|
||||
async_setup_services(hass)
|
||||
|
||||
gateway = hass.data[DOMAIN][config_entry.entry_id] = DeconzHub(
|
||||
hass, config_entry, api
|
||||
)
|
||||
await gateway.async_update_device_registry()
|
||||
hub = hass.data[DOMAIN][config_entry.entry_id] = DeconzHub(hass, config_entry, api)
|
||||
await hub.async_update_device_registry()
|
||||
|
||||
config_entry.add_update_listener(gateway.async_config_entry_updated)
|
||||
config_entry.add_update_listener(hub.async_config_entry_updated)
|
||||
|
||||
await async_setup_events(gateway)
|
||||
await async_setup_events(hub)
|
||||
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
||||
|
||||
api.start()
|
||||
|
||||
config_entry.async_on_unload(
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, gateway.shutdown)
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, hub.shutdown)
|
||||
)
|
||||
|
||||
return True
|
||||
|
@ -57,31 +55,31 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
|
||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
"""Unload deCONZ config entry."""
|
||||
gateway: DeconzHub = hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||
async_unload_events(gateway)
|
||||
hub: DeconzHub = hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||
async_unload_events(hub)
|
||||
|
||||
if not hass.data[DOMAIN]:
|
||||
async_unload_services(hass)
|
||||
|
||||
elif gateway.master:
|
||||
await async_update_master_gateway(hass, config_entry)
|
||||
new_master_gateway = next(iter(hass.data[DOMAIN].values()))
|
||||
await async_update_master_gateway(hass, new_master_gateway.config_entry)
|
||||
elif hub.master:
|
||||
await async_update_master_hub(hass, config_entry)
|
||||
new_master_hub = next(iter(hass.data[DOMAIN].values()))
|
||||
await async_update_master_hub(hass, new_master_hub.config_entry)
|
||||
|
||||
return await gateway.async_reset()
|
||||
return await hub.async_reset()
|
||||
|
||||
|
||||
async def async_update_master_gateway(
|
||||
async def async_update_master_hub(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Update master gateway boolean.
|
||||
"""Update master hub boolean.
|
||||
|
||||
Called by setup_entry and unload_entry.
|
||||
Makes sure there is always one master available.
|
||||
"""
|
||||
try:
|
||||
master_gateway = get_master_gateway(hass)
|
||||
master = master_gateway.config_entry == config_entry
|
||||
master_hub = get_master_hub(hass)
|
||||
master = master_hub.config_entry == config_entry
|
||||
except ValueError:
|
||||
master = True
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
DECONZ_TO_ALARM_STATE = {
|
||||
AncillaryControlPanel.ARMED_AWAY: STATE_ALARM_ARMED_AWAY,
|
||||
|
@ -45,9 +45,9 @@ DECONZ_TO_ALARM_STATE = {
|
|||
}
|
||||
|
||||
|
||||
def get_alarm_system_id_for_unique_id(gateway: DeconzHub, unique_id: str) -> str | None:
|
||||
def get_alarm_system_id_for_unique_id(hub: DeconzHub, unique_id: str) -> str | None:
|
||||
"""Retrieve alarm system ID the unique ID is registered to."""
|
||||
for alarm_system in gateway.api.alarm_systems.values():
|
||||
for alarm_system in hub.api.alarm_systems.values():
|
||||
if unique_id in alarm_system.devices:
|
||||
return alarm_system.resource_id
|
||||
return None
|
||||
|
@ -59,23 +59,19 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ alarm control panel devices."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_sensor(_: EventType, sensor_id: str) -> None:
|
||||
"""Add alarm control panel devices from deCONZ."""
|
||||
sensor = gateway.api.sensors.ancillary_control[sensor_id]
|
||||
if alarm_system_id := get_alarm_system_id_for_unique_id(
|
||||
gateway, sensor.unique_id
|
||||
):
|
||||
async_add_entities(
|
||||
[DeconzAlarmControlPanel(sensor, gateway, alarm_system_id)]
|
||||
)
|
||||
sensor = hub.api.sensors.ancillary_control[sensor_id]
|
||||
if alarm_system_id := get_alarm_system_id_for_unique_id(hub, sensor.unique_id):
|
||||
async_add_entities([DeconzAlarmControlPanel(sensor, hub, alarm_system_id)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors.ancillary_control,
|
||||
hub.api.sensors.ancillary_control,
|
||||
)
|
||||
|
||||
|
||||
|
@ -95,11 +91,11 @@ class DeconzAlarmControlPanel(DeconzDevice[AncillaryControl], AlarmControlPanelE
|
|||
def __init__(
|
||||
self,
|
||||
device: AncillaryControl,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
alarm_system_id: str,
|
||||
) -> None:
|
||||
"""Set up alarm control panel device."""
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
self.alarm_system_id = alarm_system_id
|
||||
|
||||
@callback
|
||||
|
@ -118,27 +114,27 @@ class DeconzAlarmControlPanel(DeconzDevice[AncillaryControl], AlarmControlPanelE
|
|||
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
||||
"""Send arm away command."""
|
||||
if code:
|
||||
await self.gateway.api.alarm_systems.arm(
|
||||
await self.hub.api.alarm_systems.arm(
|
||||
self.alarm_system_id, AlarmSystemArmAction.AWAY, code
|
||||
)
|
||||
|
||||
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
||||
"""Send arm home command."""
|
||||
if code:
|
||||
await self.gateway.api.alarm_systems.arm(
|
||||
await self.hub.api.alarm_systems.arm(
|
||||
self.alarm_system_id, AlarmSystemArmAction.STAY, code
|
||||
)
|
||||
|
||||
async def async_alarm_arm_night(self, code: str | None = None) -> None:
|
||||
"""Send arm night command."""
|
||||
if code:
|
||||
await self.gateway.api.alarm_systems.arm(
|
||||
await self.hub.api.alarm_systems.arm(
|
||||
self.alarm_system_id, AlarmSystemArmAction.NIGHT, code
|
||||
)
|
||||
|
||||
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
||||
"""Send disarm command."""
|
||||
if code:
|
||||
await self.gateway.api.alarm_systems.arm(
|
||||
await self.hub.api.alarm_systems.arm(
|
||||
self.alarm_system_id, AlarmSystemArmAction.DISARM, code
|
||||
)
|
||||
|
|
|
@ -31,7 +31,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||
|
||||
from .const import ATTR_DARK, ATTR_ON
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
_SensorDeviceT = TypeVar("_SensorDeviceT", bound=PydeconzSensorBase)
|
||||
|
||||
|
@ -168,13 +168,13 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ binary sensor."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_sensor(_: EventType, sensor_id: str) -> None:
|
||||
"""Add sensor from deCONZ."""
|
||||
sensor = gateway.api.sensors[sensor_id]
|
||||
sensor = hub.api.sensors[sensor_id]
|
||||
|
||||
for description in ENTITY_DESCRIPTIONS:
|
||||
if (
|
||||
|
@ -182,11 +182,11 @@ async def async_setup_entry(
|
|||
and not isinstance(sensor, description.instance_check)
|
||||
) or description.value_fn(sensor) is None:
|
||||
continue
|
||||
async_add_entities([DeconzBinarySensor(sensor, gateway, description)])
|
||||
async_add_entities([DeconzBinarySensor(sensor, hub, description)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors,
|
||||
hub.api.sensors,
|
||||
)
|
||||
|
||||
|
||||
|
@ -199,7 +199,7 @@ class DeconzBinarySensor(DeconzDevice[SensorResources], BinarySensorEntity):
|
|||
def __init__(
|
||||
self,
|
||||
device: SensorResources,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
description: DeconzBinarySensorDescription,
|
||||
) -> None:
|
||||
"""Initialize deCONZ binary sensor."""
|
||||
|
@ -208,7 +208,7 @@ class DeconzBinarySensor(DeconzDevice[SensorResources], BinarySensorEntity):
|
|||
self._update_key = description.update_key
|
||||
if description.name_suffix:
|
||||
self._name_suffix = description.name_suffix
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
if (
|
||||
self.entity_description.key in PROVIDES_EXTRA_ATTRIBUTES
|
||||
|
|
|
@ -20,7 +20,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzDevice, DeconzSceneMixin
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
|
@ -50,33 +50,33 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ button entity."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_scene(_: EventType, scene_id: str) -> None:
|
||||
"""Add scene button from deCONZ."""
|
||||
scene = gateway.api.scenes[scene_id]
|
||||
scene = hub.api.scenes[scene_id]
|
||||
async_add_entities(
|
||||
DeconzSceneButton(scene, gateway, description)
|
||||
DeconzSceneButton(scene, hub, description)
|
||||
for description in ENTITY_DESCRIPTIONS.get(PydeconzScene, [])
|
||||
)
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_scene,
|
||||
gateway.api.scenes,
|
||||
hub.api.scenes,
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_add_presence_sensor(_: EventType, sensor_id: str) -> None:
|
||||
"""Add presence sensor reset button from deCONZ."""
|
||||
sensor = gateway.api.sensors.presence[sensor_id]
|
||||
sensor = hub.api.sensors.presence[sensor_id]
|
||||
if sensor.presence_event is not None:
|
||||
async_add_entities([DeconzPresenceResetButton(sensor, gateway)])
|
||||
async_add_entities([DeconzPresenceResetButton(sensor, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_presence_sensor,
|
||||
gateway.api.sensors.presence,
|
||||
hub.api.sensors.presence,
|
||||
)
|
||||
|
||||
|
||||
|
@ -88,19 +88,19 @@ class DeconzSceneButton(DeconzSceneMixin, ButtonEntity):
|
|||
def __init__(
|
||||
self,
|
||||
device: PydeconzScene,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
description: DeconzButtonDescription,
|
||||
) -> None:
|
||||
"""Initialize deCONZ number entity."""
|
||||
self.entity_description: DeconzButtonDescription = description
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
self._attr_name = f"{self._attr_name} {description.suffix}"
|
||||
|
||||
async def async_press(self) -> None:
|
||||
"""Store light states into scene."""
|
||||
async_button_fn = getattr(
|
||||
self.gateway.api.scenes,
|
||||
self.hub.api.scenes,
|
||||
self.entity_description.button_fn,
|
||||
)
|
||||
await async_button_fn(self._device.group_id, self._device.id)
|
||||
|
@ -123,7 +123,7 @@ class DeconzPresenceResetButton(DeconzDevice[Presence], ButtonEntity):
|
|||
|
||||
async def async_press(self) -> None:
|
||||
"""Store reset presence state."""
|
||||
await self.gateway.api.sensors.presence.set_config(
|
||||
await self.hub.api.sensors.presence.set_config(
|
||||
id=self._device.resource_id,
|
||||
reset_presence=True,
|
||||
)
|
||||
|
|
|
@ -35,7 +35,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||
|
||||
from .const import ATTR_LOCKED, ATTR_OFFSET, ATTR_VALVE
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
DECONZ_FAN_SMART = "smart"
|
||||
|
||||
|
@ -80,18 +80,18 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ climate devices."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_climate(_: EventType, climate_id: str) -> None:
|
||||
"""Add climate from deCONZ."""
|
||||
climate = gateway.api.sensors.thermostat[climate_id]
|
||||
async_add_entities([DeconzThermostat(climate, gateway)])
|
||||
climate = hub.api.sensors.thermostat[climate_id]
|
||||
async_add_entities([DeconzThermostat(climate, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_climate,
|
||||
gateway.api.sensors.thermostat,
|
||||
hub.api.sensors.thermostat,
|
||||
)
|
||||
|
||||
|
||||
|
@ -103,9 +103,9 @@ class DeconzThermostat(DeconzDevice[Thermostat], ClimateEntity):
|
|||
_attr_temperature_unit = UnitOfTemperature.CELSIUS
|
||||
_enable_turn_on_off_backwards_compatibility = False
|
||||
|
||||
def __init__(self, device: Thermostat, gateway: DeconzHub) -> None:
|
||||
def __init__(self, device: Thermostat, hub: DeconzHub) -> None:
|
||||
"""Set up thermostat device."""
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
self._attr_hvac_modes = [
|
||||
HVACMode.HEAT,
|
||||
|
@ -149,7 +149,7 @@ class DeconzThermostat(DeconzDevice[Thermostat], ClimateEntity):
|
|||
if fan_mode not in FAN_MODE_TO_DECONZ:
|
||||
raise ValueError(f"Unsupported fan mode {fan_mode}")
|
||||
|
||||
await self.gateway.api.sensors.thermostat.set_config(
|
||||
await self.hub.api.sensors.thermostat.set_config(
|
||||
id=self._device.resource_id,
|
||||
fan_mode=FAN_MODE_TO_DECONZ[fan_mode],
|
||||
)
|
||||
|
@ -169,12 +169,12 @@ class DeconzThermostat(DeconzDevice[Thermostat], ClimateEntity):
|
|||
raise ValueError(f"Unsupported HVAC mode {hvac_mode}")
|
||||
|
||||
if len(self._attr_hvac_modes) == 2: # Only allow turn on and off thermostat
|
||||
await self.gateway.api.sensors.thermostat.set_config(
|
||||
await self.hub.api.sensors.thermostat.set_config(
|
||||
id=self._device.resource_id,
|
||||
on=hvac_mode != HVACMode.OFF,
|
||||
)
|
||||
else:
|
||||
await self.gateway.api.sensors.thermostat.set_config(
|
||||
await self.hub.api.sensors.thermostat.set_config(
|
||||
id=self._device.resource_id,
|
||||
mode=HVAC_MODE_TO_DECONZ[hvac_mode],
|
||||
)
|
||||
|
@ -208,7 +208,7 @@ class DeconzThermostat(DeconzDevice[Thermostat], ClimateEntity):
|
|||
if preset_mode not in PRESET_MODE_TO_DECONZ:
|
||||
raise ValueError(f"Unsupported preset mode {preset_mode}")
|
||||
|
||||
await self.gateway.api.sensors.thermostat.set_config(
|
||||
await self.hub.api.sensors.thermostat.set_config(
|
||||
id=self._device.resource_id,
|
||||
preset=PRESET_MODE_TO_DECONZ[preset_mode],
|
||||
)
|
||||
|
@ -237,12 +237,12 @@ class DeconzThermostat(DeconzDevice[Thermostat], ClimateEntity):
|
|||
raise ValueError(f"Expected attribute {ATTR_TEMPERATURE}")
|
||||
|
||||
if self._device.mode == ThermostatMode.COOL:
|
||||
await self.gateway.api.sensors.thermostat.set_config(
|
||||
await self.hub.api.sensors.thermostat.set_config(
|
||||
id=self._device.resource_id,
|
||||
cooling_setpoint=kwargs[ATTR_TEMPERATURE] * 100,
|
||||
)
|
||||
else:
|
||||
await self.gateway.api.sensors.thermostat.set_config(
|
||||
await self.hub.api.sensors.thermostat.set_config(
|
||||
id=self._device.resource_id,
|
||||
heating_setpoint=kwargs[ATTR_TEMPERATURE] * 100,
|
||||
)
|
||||
|
|
|
@ -52,11 +52,11 @@ CONF_MANUAL_INPUT = "Manually define gateway"
|
|||
|
||||
|
||||
@callback
|
||||
def get_master_gateway(hass: HomeAssistant) -> DeconzHub:
|
||||
def get_master_hub(hass: HomeAssistant) -> DeconzHub:
|
||||
"""Return the gateway which is marked as master."""
|
||||
for gateway in hass.data[DOMAIN].values():
|
||||
if gateway.master:
|
||||
return cast(DeconzHub, gateway)
|
||||
for hub in hass.data[DOMAIN].values():
|
||||
if hub.master:
|
||||
return cast(DeconzHub, hub)
|
||||
raise ValueError
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
DECONZ_TYPE_TO_DEVICE_CLASS = {
|
||||
ResourceType.LEVEL_CONTROLLABLE_OUTPUT.value: CoverDeviceClass.DAMPER,
|
||||
|
@ -37,17 +37,17 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up covers for deCONZ component."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_cover(_: EventType, cover_id: str) -> None:
|
||||
"""Add cover from deCONZ."""
|
||||
async_add_entities([DeconzCover(cover_id, gateway)])
|
||||
async_add_entities([DeconzCover(cover_id, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_cover,
|
||||
gateway.api.lights.covers,
|
||||
hub.api.lights.covers,
|
||||
)
|
||||
|
||||
|
||||
|
@ -56,9 +56,9 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
|
||||
TYPE = DOMAIN
|
||||
|
||||
def __init__(self, cover_id: str, gateway: DeconzHub) -> None:
|
||||
def __init__(self, cover_id: str, hub: DeconzHub) -> None:
|
||||
"""Set up cover device."""
|
||||
super().__init__(cover := gateway.api.lights.covers[cover_id], gateway)
|
||||
super().__init__(cover := hub.api.lights.covers[cover_id], hub)
|
||||
|
||||
self._attr_supported_features = (
|
||||
CoverEntityFeature.OPEN
|
||||
|
@ -92,7 +92,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
async def async_set_cover_position(self, **kwargs: Any) -> None:
|
||||
"""Move the cover to a specific position."""
|
||||
position = 100 - cast(int, kwargs[ATTR_POSITION])
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
lift=position,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
@ -100,7 +100,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Open cover."""
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
action=CoverAction.OPEN,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
@ -108,7 +108,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Close cover."""
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
action=CoverAction.CLOSE,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
@ -116,7 +116,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
|
||||
async def async_stop_cover(self, **kwargs: Any) -> None:
|
||||
"""Stop cover."""
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
action=CoverAction.STOP,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
@ -132,7 +132,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
|
||||
"""Tilt the cover to a specific position."""
|
||||
position = 100 - cast(int, kwargs[ATTR_TILT_POSITION])
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
tilt=position,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
@ -140,7 +140,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
|
||||
async def async_open_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Open cover tilt."""
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
tilt=0,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
@ -148,7 +148,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
|
||||
async def async_close_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Close cover tilt."""
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
tilt=100,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
@ -156,7 +156,7 @@ class DeconzCover(DeconzDevice[Cover], CoverEntity):
|
|||
|
||||
async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Stop cover tilt."""
|
||||
await self.gateway.api.lights.covers.set_state(
|
||||
await self.hub.api.lights.covers.set_state(
|
||||
id=self._device.resource_id,
|
||||
action=CoverAction.STOP,
|
||||
legacy_mode=self.legacy_mode,
|
||||
|
|
|
@ -33,11 +33,11 @@ class DeconzBase(Generic[_DeviceT]):
|
|||
def __init__(
|
||||
self,
|
||||
device: _DeviceT,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
) -> None:
|
||||
"""Set up device and add update callback to get data from websocket."""
|
||||
self._device: _DeviceT = device
|
||||
self.gateway = gateway
|
||||
self.hub = hub
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
|
@ -67,7 +67,7 @@ class DeconzBase(Generic[_DeviceT]):
|
|||
model=self._device.model_id,
|
||||
name=self._device.name,
|
||||
sw_version=self._device.software_version,
|
||||
via_device=(DECONZ_DOMAIN, self.gateway.api.config.bridge_id),
|
||||
via_device=(DECONZ_DOMAIN, self.hub.api.config.bridge_id),
|
||||
)
|
||||
|
||||
|
||||
|
@ -85,11 +85,11 @@ class DeconzDevice(DeconzBase[_DeviceT], Entity):
|
|||
def __init__(
|
||||
self,
|
||||
device: _DeviceT,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
) -> None:
|
||||
"""Set up device and add update callback to get data from websocket."""
|
||||
super().__init__(device, gateway)
|
||||
self.gateway.entities[self.TYPE].add(self.unique_id)
|
||||
super().__init__(device, hub)
|
||||
self.hub.entities[self.TYPE].add(self.unique_id)
|
||||
|
||||
self._attr_name = self._device.name
|
||||
if self._name_suffix is not None:
|
||||
|
@ -103,11 +103,11 @@ class DeconzDevice(DeconzBase[_DeviceT], Entity):
|
|||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe to device events."""
|
||||
self._device.register_callback(self.async_update_callback)
|
||||
self.gateway.deconz_ids[self.entity_id] = self._device.deconz_id
|
||||
self.hub.deconz_ids[self.entity_id] = self._device.deconz_id
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
self.gateway.signal_reachable,
|
||||
self.hub.signal_reachable,
|
||||
self.async_update_connection_state,
|
||||
)
|
||||
)
|
||||
|
@ -115,8 +115,8 @@ class DeconzDevice(DeconzBase[_DeviceT], Entity):
|
|||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect device object when removed."""
|
||||
self._device.remove_callback(self.async_update_callback)
|
||||
del self.gateway.deconz_ids[self.entity_id]
|
||||
self.gateway.entities[self.TYPE].remove(self.unique_id)
|
||||
del self.hub.deconz_ids[self.entity_id]
|
||||
self.hub.entities[self.TYPE].remove(self.unique_id)
|
||||
|
||||
@callback
|
||||
def async_update_connection_state(self) -> None:
|
||||
|
@ -126,7 +126,7 @@ class DeconzDevice(DeconzBase[_DeviceT], Entity):
|
|||
@callback
|
||||
def async_update_callback(self) -> None:
|
||||
"""Update the device's state."""
|
||||
if self.gateway.ignore_state_updates:
|
||||
if self.hub.ignore_state_updates:
|
||||
return
|
||||
|
||||
if self._update_keys is not None and not self._device.changed_keys.intersection(
|
||||
|
@ -140,8 +140,8 @@ class DeconzDevice(DeconzBase[_DeviceT], Entity):
|
|||
def available(self) -> bool:
|
||||
"""Return True if device is available."""
|
||||
if isinstance(self._device, PydeconzScene):
|
||||
return self.gateway.available
|
||||
return self.gateway.available and self._device.reachable # type: ignore[union-attr]
|
||||
return self.hub.available
|
||||
return self.hub.available and self._device.reachable # type: ignore[union-attr]
|
||||
|
||||
|
||||
class DeconzSceneMixin(DeconzDevice[PydeconzScene]):
|
||||
|
@ -152,23 +152,23 @@ class DeconzSceneMixin(DeconzDevice[PydeconzScene]):
|
|||
def __init__(
|
||||
self,
|
||||
device: PydeconzScene,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
) -> None:
|
||||
"""Set up a scene."""
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
self.group = self.gateway.api.groups[device.group_id]
|
||||
self.group = self.hub.api.groups[device.group_id]
|
||||
|
||||
self._attr_name = device.name
|
||||
self._group_identifier = self.get_parent_identifier()
|
||||
|
||||
def get_device_identifier(self) -> str:
|
||||
"""Describe a unique identifier for this scene."""
|
||||
return f"{self.gateway.bridgeid}{self._device.deconz_id}"
|
||||
return f"{self.hub.bridgeid}{self._device.deconz_id}"
|
||||
|
||||
def get_parent_identifier(self) -> str:
|
||||
"""Describe a unique identifier for group this scene belongs to."""
|
||||
return f"{self.gateway.bridgeid}-{self.group.deconz_id}"
|
||||
return f"{self.hub.bridgeid}-{self.group.deconz_id}"
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
|
@ -183,5 +183,5 @@ class DeconzSceneMixin(DeconzDevice[PydeconzScene]):
|
|||
manufacturer="Dresden Elektronik",
|
||||
model="deCONZ group",
|
||||
name=self.group.name,
|
||||
via_device=(DECONZ_DOMAIN, self.gateway.api.config.bridge_id),
|
||||
via_device=(DECONZ_DOMAIN, self.hub.api.config.bridge_id),
|
||||
)
|
||||
|
|
|
@ -55,57 +55,57 @@ RELATIVE_ROTARY_DECONZ_TO_EVENT = {
|
|||
}
|
||||
|
||||
|
||||
async def async_setup_events(gateway: DeconzHub) -> None:
|
||||
async def async_setup_events(hub: DeconzHub) -> None:
|
||||
"""Set up the deCONZ events."""
|
||||
|
||||
@callback
|
||||
def async_add_sensor(_: EventType, sensor_id: str) -> None:
|
||||
"""Create DeconzEvent."""
|
||||
new_event: DeconzAlarmEvent | DeconzEvent | DeconzPresenceEvent | DeconzRelativeRotaryEvent
|
||||
sensor = gateway.api.sensors[sensor_id]
|
||||
sensor = hub.api.sensors[sensor_id]
|
||||
|
||||
if isinstance(sensor, Switch):
|
||||
new_event = DeconzEvent(sensor, gateway)
|
||||
new_event = DeconzEvent(sensor, hub)
|
||||
|
||||
elif isinstance(sensor, AncillaryControl):
|
||||
new_event = DeconzAlarmEvent(sensor, gateway)
|
||||
new_event = DeconzAlarmEvent(sensor, hub)
|
||||
|
||||
elif isinstance(sensor, Presence):
|
||||
if sensor.presence_event is None:
|
||||
return
|
||||
new_event = DeconzPresenceEvent(sensor, gateway)
|
||||
new_event = DeconzPresenceEvent(sensor, hub)
|
||||
|
||||
elif isinstance(sensor, RelativeRotary):
|
||||
new_event = DeconzRelativeRotaryEvent(sensor, gateway)
|
||||
new_event = DeconzRelativeRotaryEvent(sensor, hub)
|
||||
|
||||
gateway.hass.async_create_task(new_event.async_update_device_registry())
|
||||
gateway.events.append(new_event)
|
||||
hub.hass.async_create_task(new_event.async_update_device_registry())
|
||||
hub.events.append(new_event)
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors.switch,
|
||||
hub.api.sensors.switch,
|
||||
)
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors.ancillary_control,
|
||||
hub.api.sensors.ancillary_control,
|
||||
)
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors.presence,
|
||||
hub.api.sensors.presence,
|
||||
)
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors.relative_rotary,
|
||||
hub.api.sensors.relative_rotary,
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_unload_events(gateway: DeconzHub) -> None:
|
||||
def async_unload_events(hub: DeconzHub) -> None:
|
||||
"""Unload all deCONZ events."""
|
||||
for event in gateway.events:
|
||||
for event in hub.events:
|
||||
event.async_will_remove_from_hass()
|
||||
|
||||
gateway.events.clear()
|
||||
hub.events.clear()
|
||||
|
||||
|
||||
class DeconzEventBase(DeconzBase):
|
||||
|
@ -118,10 +118,10 @@ class DeconzEventBase(DeconzBase):
|
|||
def __init__(
|
||||
self,
|
||||
device: AncillaryControl | Presence | RelativeRotary | Switch,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
) -> None:
|
||||
"""Register callback that will be used for signals."""
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
self._unsubscribe = device.subscribe(self.async_update_callback)
|
||||
|
||||
|
@ -145,10 +145,10 @@ class DeconzEventBase(DeconzBase):
|
|||
if not self.device_info:
|
||||
return
|
||||
|
||||
device_registry = dr.async_get(self.gateway.hass)
|
||||
device_registry = dr.async_get(self.hub.hass)
|
||||
|
||||
entry = device_registry.async_get_or_create(
|
||||
config_entry_id=self.gateway.config_entry.entry_id, **self.device_info
|
||||
config_entry_id=self.hub.config_entry.entry_id, **self.device_info
|
||||
)
|
||||
self.device_id = entry.id
|
||||
|
||||
|
@ -165,10 +165,7 @@ class DeconzEvent(DeconzEventBase):
|
|||
@callback
|
||||
def async_update_callback(self) -> None:
|
||||
"""Fire the event if reason is that state is updated."""
|
||||
if (
|
||||
self.gateway.ignore_state_updates
|
||||
or "state" not in self._device.changed_keys
|
||||
):
|
||||
if self.hub.ignore_state_updates or "state" not in self._device.changed_keys:
|
||||
return
|
||||
|
||||
data: dict[str, Any] = {
|
||||
|
@ -189,7 +186,7 @@ class DeconzEvent(DeconzEventBase):
|
|||
if self._device.xy is not None:
|
||||
data[CONF_XY] = self._device.xy
|
||||
|
||||
self.gateway.hass.bus.async_fire(CONF_DECONZ_EVENT, data)
|
||||
self.hub.hass.bus.async_fire(CONF_DECONZ_EVENT, data)
|
||||
|
||||
|
||||
class DeconzAlarmEvent(DeconzEventBase):
|
||||
|
@ -201,7 +198,7 @@ class DeconzAlarmEvent(DeconzEventBase):
|
|||
def async_update_callback(self) -> None:
|
||||
"""Fire the event if reason is new action is updated."""
|
||||
if (
|
||||
self.gateway.ignore_state_updates
|
||||
self.hub.ignore_state_updates
|
||||
or "action" not in self._device.changed_keys
|
||||
or self._device.action not in SUPPORTED_DECONZ_ALARM_EVENTS
|
||||
):
|
||||
|
@ -214,7 +211,7 @@ class DeconzAlarmEvent(DeconzEventBase):
|
|||
CONF_EVENT: self._device.action.value,
|
||||
}
|
||||
|
||||
self.gateway.hass.bus.async_fire(CONF_DECONZ_ALARM_EVENT, data)
|
||||
self.hub.hass.bus.async_fire(CONF_DECONZ_ALARM_EVENT, data)
|
||||
|
||||
|
||||
class DeconzPresenceEvent(DeconzEventBase):
|
||||
|
@ -226,7 +223,7 @@ class DeconzPresenceEvent(DeconzEventBase):
|
|||
def async_update_callback(self) -> None:
|
||||
"""Fire the event if reason is new action is updated."""
|
||||
if (
|
||||
self.gateway.ignore_state_updates
|
||||
self.hub.ignore_state_updates
|
||||
or "presenceevent" not in self._device.changed_keys
|
||||
or self._device.presence_event not in SUPPORTED_DECONZ_PRESENCE_EVENTS
|
||||
):
|
||||
|
@ -239,7 +236,7 @@ class DeconzPresenceEvent(DeconzEventBase):
|
|||
CONF_EVENT: self._device.presence_event.value,
|
||||
}
|
||||
|
||||
self.gateway.hass.bus.async_fire(CONF_DECONZ_PRESENCE_EVENT, data)
|
||||
self.hub.hass.bus.async_fire(CONF_DECONZ_PRESENCE_EVENT, data)
|
||||
|
||||
|
||||
class DeconzRelativeRotaryEvent(DeconzEventBase):
|
||||
|
@ -251,7 +248,7 @@ class DeconzRelativeRotaryEvent(DeconzEventBase):
|
|||
def async_update_callback(self) -> None:
|
||||
"""Fire the event if reason is new action is updated."""
|
||||
if (
|
||||
self.gateway.ignore_state_updates
|
||||
self.hub.ignore_state_updates
|
||||
or "rotaryevent" not in self._device.changed_keys
|
||||
):
|
||||
return
|
||||
|
@ -265,4 +262,4 @@ class DeconzRelativeRotaryEvent(DeconzEventBase):
|
|||
ATTR_DURATION: self._device.expected_event_duration,
|
||||
}
|
||||
|
||||
self.gateway.hass.bus.async_fire(CONF_DECONZ_RELATIVE_ROTARY_EVENT, data)
|
||||
self.hub.hass.bus.async_fire(CONF_DECONZ_RELATIVE_ROTARY_EVENT, data)
|
||||
|
|
|
@ -656,9 +656,9 @@ def _get_deconz_event_from_device(
|
|||
device: dr.DeviceEntry,
|
||||
) -> DeconzAlarmEvent | DeconzEvent | DeconzPresenceEvent | DeconzRelativeRotaryEvent:
|
||||
"""Resolve deconz event from device."""
|
||||
gateways: dict[str, DeconzHub] = hass.data.get(DOMAIN, {})
|
||||
for gateway in gateways.values():
|
||||
for deconz_event in gateway.events:
|
||||
hubs: dict[str, DeconzHub] = hass.data.get(DOMAIN, {})
|
||||
for hub in hubs.values():
|
||||
for deconz_event in hub.events:
|
||||
if device.id == deconz_event.device_id:
|
||||
return deconz_event
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||
from homeassistant.const import CONF_API_KEY, CONF_UNIQUE_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .hub import get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
REDACT_CONFIG = {CONF_API_KEY, CONF_UNIQUE_ID}
|
||||
REDACT_DECONZ_CONFIG = {"bridgeid", "mac", "panid"}
|
||||
|
@ -19,29 +19,27 @@ async def async_get_config_entry_diagnostics(
|
|||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
diag: dict[str, Any] = {}
|
||||
|
||||
diag["config"] = async_redact_data(config_entry.as_dict(), REDACT_CONFIG)
|
||||
diag["deconz_config"] = async_redact_data(
|
||||
gateway.api.config.raw, REDACT_DECONZ_CONFIG
|
||||
)
|
||||
diag["deconz_config"] = async_redact_data(hub.api.config.raw, REDACT_DECONZ_CONFIG)
|
||||
diag["websocket_state"] = (
|
||||
gateway.api.websocket.state.value if gateway.api.websocket else "Unknown"
|
||||
hub.api.websocket.state.value if hub.api.websocket else "Unknown"
|
||||
)
|
||||
diag["deconz_ids"] = gateway.deconz_ids
|
||||
diag["entities"] = gateway.entities
|
||||
diag["deconz_ids"] = hub.deconz_ids
|
||||
diag["entities"] = hub.entities
|
||||
diag["events"] = {
|
||||
event.serial: {
|
||||
"event_id": event.event_id,
|
||||
"event_type": type(event).__name__,
|
||||
}
|
||||
for event in gateway.events
|
||||
for event in hub.events
|
||||
}
|
||||
diag["alarm_systems"] = {k: v.raw for k, v in gateway.api.alarm_systems.items()}
|
||||
diag["groups"] = {k: v.raw for k, v in gateway.api.groups.items()}
|
||||
diag["lights"] = {k: v.raw for k, v in gateway.api.lights.items()}
|
||||
diag["scenes"] = {k: v.raw for k, v in gateway.api.scenes.items()}
|
||||
diag["sensors"] = {k: v.raw for k, v in gateway.api.sensors.items()}
|
||||
diag["alarm_systems"] = {k: v.raw for k, v in hub.api.alarm_systems.items()}
|
||||
diag["groups"] = {k: v.raw for k, v in hub.api.groups.items()}
|
||||
diag["lights"] = {k: v.raw for k, v in hub.api.lights.items()}
|
||||
diag["scenes"] = {k: v.raw for k, v in hub.api.scenes.items()}
|
||||
diag["sensors"] = {k: v.raw for k, v in hub.api.sensors.items()}
|
||||
|
||||
return diag
|
||||
|
|
|
@ -17,7 +17,7 @@ from homeassistant.util.percentage import (
|
|||
)
|
||||
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
ORDERED_NAMED_FAN_SPEEDS: list[LightFanSpeed] = [
|
||||
LightFanSpeed.PERCENT_25,
|
||||
|
@ -33,20 +33,20 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up fans for deCONZ component."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_fan(_: EventType, fan_id: str) -> None:
|
||||
"""Add fan from deCONZ."""
|
||||
fan = gateway.api.lights.lights[fan_id]
|
||||
fan = hub.api.lights.lights[fan_id]
|
||||
if not fan.supports_fan_speed:
|
||||
return
|
||||
async_add_entities([DeconzFan(fan, gateway)])
|
||||
async_add_entities([DeconzFan(fan, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_fan,
|
||||
gateway.api.lights.lights,
|
||||
hub.api.lights.lights,
|
||||
)
|
||||
|
||||
|
||||
|
@ -58,9 +58,9 @@ class DeconzFan(DeconzDevice[Light], FanEntity):
|
|||
|
||||
_attr_supported_features = FanEntityFeature.SET_SPEED
|
||||
|
||||
def __init__(self, device: Light, gateway: DeconzHub) -> None:
|
||||
def __init__(self, device: Light, hub: DeconzHub) -> None:
|
||||
"""Set up fan."""
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
_attr_speed_count = len(ORDERED_NAMED_FAN_SPEEDS)
|
||||
if device.fan_speed in ORDERED_NAMED_FAN_SPEEDS:
|
||||
self._default_on_speed = device.fan_speed
|
||||
|
@ -92,7 +92,7 @@ class DeconzFan(DeconzDevice[Light], FanEntity):
|
|||
"""Set the speed percentage of the fan."""
|
||||
if percentage == 0:
|
||||
return await self.async_turn_off()
|
||||
await self.gateway.api.lights.lights.set_state(
|
||||
await self.hub.api.lights.lights.set_state(
|
||||
id=self._device.resource_id,
|
||||
fan_speed=percentage_to_ordered_list_item(
|
||||
ORDERED_NAMED_FAN_SPEEDS, percentage
|
||||
|
@ -109,14 +109,14 @@ class DeconzFan(DeconzDevice[Light], FanEntity):
|
|||
if percentage is not None:
|
||||
await self.async_set_percentage(percentage)
|
||||
return
|
||||
await self.gateway.api.lights.lights.set_state(
|
||||
await self.hub.api.lights.lights.set_state(
|
||||
id=self._device.resource_id,
|
||||
fan_speed=self._default_on_speed,
|
||||
)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off fan."""
|
||||
await self.gateway.api.lights.lights.set_state(
|
||||
await self.hub.api.lights.lights.set_state(
|
||||
id=self._device.resource_id,
|
||||
fan_speed=LightFanSpeed.OFF,
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""Internal functionality not part of HA infrastructure."""
|
||||
|
||||
from .api import get_deconz_api # noqa: F401
|
||||
from .config import DeconzConfig # noqa: F401
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry # noqa: F401
|
||||
from .hub import DeconzHub # noqa: F401
|
||||
|
|
|
@ -94,6 +94,12 @@ class DeconzHub:
|
|||
self.deconz_groups: set[tuple[Callable[[EventType, str], None], str]] = set()
|
||||
self.ignored_devices: set[tuple[Callable[[EventType, str], None], str]] = set()
|
||||
|
||||
@callback
|
||||
@staticmethod
|
||||
def get_hub(hass: HomeAssistant, config_entry: ConfigEntry) -> DeconzHub:
|
||||
"""Return hub with a matching config entry ID."""
|
||||
return cast(DeconzHub, hass.data[DECONZ_DOMAIN][config_entry.entry_id])
|
||||
|
||||
@property
|
||||
def bridgeid(self) -> str:
|
||||
"""Return the unique identifier of the gateway."""
|
||||
|
@ -215,16 +221,16 @@ class DeconzHub:
|
|||
# A race condition can occur if multiple config entries are
|
||||
# unloaded in parallel
|
||||
return
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
previous_config = gateway.config
|
||||
gateway.config = DeconzConfig.from_config_entry(config_entry)
|
||||
if previous_config.host != gateway.config.host:
|
||||
gateway.api.close()
|
||||
gateway.api.host = gateway.config.host
|
||||
gateway.api.start()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
previous_config = hub.config
|
||||
hub.config = DeconzConfig.from_config_entry(config_entry)
|
||||
if previous_config.host != hub.config.host:
|
||||
hub.api.close()
|
||||
hub.api.host = hub.config.host
|
||||
hub.api.start()
|
||||
return
|
||||
|
||||
await gateway.options_updated(previous_config)
|
||||
await hub.options_updated(previous_config)
|
||||
|
||||
async def options_updated(self, previous_config: DeconzConfig) -> None:
|
||||
"""Manage entities affected by config entry options."""
|
||||
|
@ -292,11 +298,3 @@ class DeconzHub:
|
|||
|
||||
self.deconz_ids = {}
|
||||
return True
|
||||
|
||||
|
||||
@callback
|
||||
def get_gateway_from_config_entry(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> DeconzHub:
|
||||
"""Return gateway with a matching config entry ID."""
|
||||
return cast(DeconzHub, hass.data[DECONZ_DOMAIN][config_entry.entry_id])
|
||||
|
|
|
@ -36,7 +36,7 @@ from homeassistant.util.color import color_hs_to_xy
|
|||
|
||||
from .const import DOMAIN as DECONZ_DOMAIN, POWER_PLUGS
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
DECONZ_GROUP = "is_deconz_group"
|
||||
EFFECT_TO_DECONZ = {
|
||||
|
@ -111,13 +111,13 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ lights and groups from a config entry."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
# On/Off Output should be switch not light 2022.5
|
||||
for light in gateway.api.lights.lights.values():
|
||||
for light in hub.api.lights.lights.values():
|
||||
if light.type == ResourceType.ON_OFF_OUTPUT.value and (
|
||||
entity_id := entity_registry.async_get_entity_id(
|
||||
DOMAIN, DECONZ_DOMAIN, light.unique_id
|
||||
|
@ -128,15 +128,15 @@ async def async_setup_entry(
|
|||
@callback
|
||||
def async_add_light(_: EventType, light_id: str) -> None:
|
||||
"""Add light from deCONZ."""
|
||||
light = gateway.api.lights.lights[light_id]
|
||||
light = hub.api.lights.lights[light_id]
|
||||
if light.type in POWER_PLUGS:
|
||||
return
|
||||
|
||||
async_add_entities([DeconzLight(light, gateway)])
|
||||
async_add_entities([DeconzLight(light, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_light,
|
||||
gateway.api.lights.lights,
|
||||
hub.api.lights.lights,
|
||||
)
|
||||
|
||||
@callback
|
||||
|
@ -145,20 +145,20 @@ async def async_setup_entry(
|
|||
|
||||
Update group states based on its sum of related lights.
|
||||
"""
|
||||
if (group := gateway.api.groups[group_id]) and not group.lights:
|
||||
if (group := hub.api.groups[group_id]) and not group.lights:
|
||||
return
|
||||
|
||||
first = True
|
||||
for light_id in group.lights:
|
||||
if (light := gateway.api.lights.lights.get(light_id)) and light.reachable:
|
||||
if (light := hub.api.lights.lights.get(light_id)) and light.reachable:
|
||||
group.update_color_state(light, update_all_attributes=first)
|
||||
first = False
|
||||
|
||||
async_add_entities([DeconzGroup(group, gateway)])
|
||||
async_add_entities([DeconzGroup(group, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_group,
|
||||
gateway.api.groups,
|
||||
hub.api.groups,
|
||||
)
|
||||
|
||||
|
||||
|
@ -168,15 +168,15 @@ class DeconzBaseLight(DeconzDevice[_LightDeviceT], LightEntity):
|
|||
TYPE = DOMAIN
|
||||
_attr_color_mode = ColorMode.UNKNOWN
|
||||
|
||||
def __init__(self, device: _LightDeviceT, gateway: DeconzHub) -> None:
|
||||
def __init__(self, device: _LightDeviceT, hub: DeconzHub) -> None:
|
||||
"""Set up light."""
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
self.api: GroupHandler | LightHandler
|
||||
if isinstance(self._device, Light):
|
||||
self.api = self.gateway.api.lights.lights
|
||||
self.api = self.hub.api.lights.lights
|
||||
elif isinstance(self._device, Group):
|
||||
self.api = self.gateway.api.groups
|
||||
self.api = self.hub.api.groups
|
||||
|
||||
self._attr_supported_color_modes: set[ColorMode] = set()
|
||||
|
||||
|
@ -324,7 +324,7 @@ class DeconzLight(DeconzBaseLight[Light]):
|
|||
super().async_update_callback()
|
||||
|
||||
if self._device.reachable and "attr" not in self._device.changed_keys:
|
||||
for group in self.gateway.api.groups.values():
|
||||
for group in self.hub.api.groups.values():
|
||||
if self._device.resource_id in group.lights:
|
||||
group.update_color_state(self._device)
|
||||
|
||||
|
@ -334,10 +334,10 @@ class DeconzGroup(DeconzBaseLight[Group]):
|
|||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(self, device: Group, gateway: DeconzHub) -> None:
|
||||
def __init__(self, device: Group, hub: DeconzHub) -> None:
|
||||
"""Set up group and create an unique id."""
|
||||
self._unique_id = f"{gateway.bridgeid}-{device.deconz_id}"
|
||||
super().__init__(device, gateway)
|
||||
self._unique_id = f"{hub.bridgeid}-{device.deconz_id}"
|
||||
super().__init__(device, hub)
|
||||
|
||||
self._attr_name = None
|
||||
|
||||
|
@ -354,7 +354,7 @@ class DeconzGroup(DeconzBaseLight[Group]):
|
|||
manufacturer="Dresden Elektronik",
|
||||
model="deCONZ group",
|
||||
name=self._device.name,
|
||||
via_device=(DECONZ_DOMAIN, self.gateway.api.config.bridge_id),
|
||||
via_device=(DECONZ_DOMAIN, self.hub.api.config.bridge_id),
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
|
@ -14,7 +14,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -23,29 +23,29 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up locks for deCONZ component."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_lock_from_light(_: EventType, lock_id: str) -> None:
|
||||
"""Add lock from deCONZ."""
|
||||
lock = gateway.api.lights.locks[lock_id]
|
||||
async_add_entities([DeconzLock(lock, gateway)])
|
||||
lock = hub.api.lights.locks[lock_id]
|
||||
async_add_entities([DeconzLock(lock, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_lock_from_light,
|
||||
gateway.api.lights.locks,
|
||||
hub.api.lights.locks,
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_add_lock_from_sensor(_: EventType, lock_id: str) -> None:
|
||||
"""Add lock from deCONZ."""
|
||||
lock = gateway.api.sensors.door_lock[lock_id]
|
||||
async_add_entities([DeconzLock(lock, gateway)])
|
||||
lock = hub.api.sensors.door_lock[lock_id]
|
||||
async_add_entities([DeconzLock(lock, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_lock_from_sensor,
|
||||
gateway.api.sensors.door_lock,
|
||||
hub.api.sensors.door_lock,
|
||||
always_ignore_clip_sensors=True,
|
||||
)
|
||||
|
||||
|
@ -63,12 +63,12 @@ class DeconzLock(DeconzDevice[DoorLock | Lock], LockEntity):
|
|||
async def async_lock(self, **kwargs: Any) -> None:
|
||||
"""Lock the lock."""
|
||||
if isinstance(self._device, DoorLock):
|
||||
await self.gateway.api.sensors.door_lock.set_config(
|
||||
await self.hub.api.sensors.door_lock.set_config(
|
||||
id=self._device.resource_id,
|
||||
lock=True,
|
||||
)
|
||||
else:
|
||||
await self.gateway.api.lights.locks.set_state(
|
||||
await self.hub.api.lights.locks.set_state(
|
||||
id=self._device.resource_id,
|
||||
lock=True,
|
||||
)
|
||||
|
@ -76,12 +76,12 @@ class DeconzLock(DeconzDevice[DoorLock | Lock], LockEntity):
|
|||
async def async_unlock(self, **kwargs: Any) -> None:
|
||||
"""Unlock the lock."""
|
||||
if isinstance(self._device, DoorLock):
|
||||
await self.gateway.api.sensors.door_lock.set_config(
|
||||
await self.hub.api.sensors.door_lock.set_config(
|
||||
id=self._device.resource_id,
|
||||
lock=False,
|
||||
)
|
||||
else:
|
||||
await self.gateway.api.lights.locks.set_state(
|
||||
await self.hub.api.lights.locks.set_state(
|
||||
id=self._device.resource_id,
|
||||
lock=False,
|
||||
)
|
||||
|
|
|
@ -23,7 +23,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
T = TypeVar("T", Presence, PydeconzSensorBase)
|
||||
|
||||
|
@ -73,13 +73,13 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ number entity."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_sensor(_: EventType, sensor_id: str) -> None:
|
||||
"""Add sensor from deCONZ."""
|
||||
sensor = gateway.api.sensors.presence[sensor_id]
|
||||
sensor = hub.api.sensors.presence[sensor_id]
|
||||
|
||||
for description in ENTITY_DESCRIPTIONS:
|
||||
if (
|
||||
|
@ -87,11 +87,11 @@ async def async_setup_entry(
|
|||
or description.value_fn(sensor) is None
|
||||
):
|
||||
continue
|
||||
async_add_entities([DeconzNumber(sensor, gateway, description)])
|
||||
async_add_entities([DeconzNumber(sensor, hub, description)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors.presence,
|
||||
hub.api.sensors.presence,
|
||||
always_ignore_clip_sensors=True,
|
||||
)
|
||||
|
||||
|
@ -105,7 +105,7 @@ class DeconzNumber(DeconzDevice[SensorResources], NumberEntity):
|
|||
def __init__(
|
||||
self,
|
||||
device: SensorResources,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
description: DeconzNumberDescription,
|
||||
) -> None:
|
||||
"""Initialize deCONZ number entity."""
|
||||
|
@ -113,7 +113,7 @@ class DeconzNumber(DeconzDevice[SensorResources], NumberEntity):
|
|||
self.unique_id_suffix = description.key
|
||||
self._name_suffix = description.name_suffix
|
||||
self._update_key = description.update_key
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
@property
|
||||
def native_value(self) -> float | None:
|
||||
|
@ -123,7 +123,7 @@ class DeconzNumber(DeconzDevice[SensorResources], NumberEntity):
|
|||
async def async_set_native_value(self, value: float) -> None:
|
||||
"""Set sensor config."""
|
||||
await self.entity_description.set_fn(
|
||||
self.gateway.api,
|
||||
self.hub.api,
|
||||
self._device.resource_id,
|
||||
int(value),
|
||||
)
|
||||
|
|
|
@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzSceneMixin
|
||||
from .hub import get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -21,18 +21,18 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up scenes for deCONZ integration."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_scene(_: EventType, scene_id: str) -> None:
|
||||
"""Add scene from deCONZ."""
|
||||
scene = gateway.api.scenes[scene_id]
|
||||
async_add_entities([DeconzScene(scene, gateway)])
|
||||
scene = hub.api.scenes[scene_id]
|
||||
async_add_entities([DeconzScene(scene, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_scene,
|
||||
gateway.api.scenes,
|
||||
hub.api.scenes,
|
||||
)
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ class DeconzScene(DeconzSceneMixin, Scene):
|
|||
|
||||
async def async_activate(self, **kwargs: Any) -> None:
|
||||
"""Activate the scene."""
|
||||
await self.gateway.api.scenes.recall(
|
||||
await self.hub.api.scenes.recall(
|
||||
self._device.group_id,
|
||||
self._device.id,
|
||||
)
|
||||
|
|
|
@ -17,7 +17,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
SENSITIVITY_TO_DECONZ = {
|
||||
"High": PresenceConfigSensitivity.HIGH.value,
|
||||
|
@ -33,25 +33,25 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ button entity."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_presence_sensor(_: EventType, sensor_id: str) -> None:
|
||||
"""Add presence select entity from deCONZ."""
|
||||
sensor = gateway.api.sensors.presence[sensor_id]
|
||||
sensor = hub.api.sensors.presence[sensor_id]
|
||||
if sensor.presence_event is not None:
|
||||
async_add_entities(
|
||||
[
|
||||
DeconzPresenceDeviceModeSelect(sensor, gateway),
|
||||
DeconzPresenceSensitivitySelect(sensor, gateway),
|
||||
DeconzPresenceTriggerDistanceSelect(sensor, gateway),
|
||||
DeconzPresenceDeviceModeSelect(sensor, hub),
|
||||
DeconzPresenceSensitivitySelect(sensor, hub),
|
||||
DeconzPresenceTriggerDistanceSelect(sensor, hub),
|
||||
]
|
||||
)
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_presence_sensor,
|
||||
gateway.api.sensors.presence,
|
||||
hub.api.sensors.presence,
|
||||
)
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ class DeconzPresenceDeviceModeSelect(DeconzDevice[Presence], SelectEntity):
|
|||
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
await self.gateway.api.sensors.presence.set_config(
|
||||
await self.hub.api.sensors.presence.set_config(
|
||||
id=self._device.resource_id,
|
||||
device_mode=PresenceConfigDeviceMode(option),
|
||||
)
|
||||
|
@ -106,7 +106,7 @@ class DeconzPresenceSensitivitySelect(DeconzDevice[Presence], SelectEntity):
|
|||
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
await self.gateway.api.sensors.presence.set_config(
|
||||
await self.hub.api.sensors.presence.set_config(
|
||||
id=self._device.resource_id,
|
||||
sensitivity=SENSITIVITY_TO_DECONZ[option],
|
||||
)
|
||||
|
@ -137,7 +137,7 @@ class DeconzPresenceTriggerDistanceSelect(DeconzDevice[Presence], SelectEntity):
|
|||
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
await self.gateway.api.sensors.presence.set_config(
|
||||
await self.hub.api.sensors.presence.set_config(
|
||||
id=self._device.resource_id,
|
||||
trigger_distance=PresenceConfigTriggerDistance(option),
|
||||
)
|
||||
|
|
|
@ -53,7 +53,7 @@ import homeassistant.util.dt as dt_util
|
|||
|
||||
from .const import ATTR_DARK, ATTR_ON
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import DeconzHub, get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
PROVIDES_EXTRA_ATTRIBUTES = (
|
||||
"battery",
|
||||
|
@ -295,8 +295,8 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the deCONZ sensors."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
known_device_entities: dict[str, set[str]] = {
|
||||
description.key: set()
|
||||
|
@ -307,7 +307,7 @@ async def async_setup_entry(
|
|||
@callback
|
||||
def async_add_sensor(_: EventType, sensor_id: str) -> None:
|
||||
"""Add sensor from deCONZ."""
|
||||
sensor = gateway.api.sensors[sensor_id]
|
||||
sensor = hub.api.sensors[sensor_id]
|
||||
entities: list[DeconzSensor] = []
|
||||
|
||||
for description in ENTITY_DESCRIPTIONS:
|
||||
|
@ -333,20 +333,20 @@ async def async_setup_entry(
|
|||
known_device_entities[description.key].add(unique_id)
|
||||
if no_sensor_data and description.key == "battery":
|
||||
DeconzBatteryTracker(
|
||||
sensor_id, gateway, description, async_add_entities
|
||||
sensor_id, hub, description, async_add_entities
|
||||
)
|
||||
continue
|
||||
|
||||
if no_sensor_data:
|
||||
continue
|
||||
|
||||
entities.append(DeconzSensor(sensor, gateway, description))
|
||||
entities.append(DeconzSensor(sensor, hub, description))
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_sensor,
|
||||
gateway.api.sensors,
|
||||
hub.api.sensors,
|
||||
)
|
||||
|
||||
|
||||
|
@ -359,7 +359,7 @@ class DeconzSensor(DeconzDevice[SensorResources], SensorEntity):
|
|||
def __init__(
|
||||
self,
|
||||
device: SensorResources,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
description: DeconzSensorDescription,
|
||||
) -> None:
|
||||
"""Initialize deCONZ sensor."""
|
||||
|
@ -368,7 +368,7 @@ class DeconzSensor(DeconzDevice[SensorResources], SensorEntity):
|
|||
self._update_key = description.update_key
|
||||
if description.name_suffix:
|
||||
self._name_suffix = description.name_suffix
|
||||
super().__init__(device, gateway)
|
||||
super().__init__(device, hub)
|
||||
|
||||
if (
|
||||
self.entity_description.key in PROVIDES_EXTRA_ATTRIBUTES
|
||||
|
@ -413,7 +413,7 @@ class DeconzSensor(DeconzDevice[SensorResources], SensorEntity):
|
|||
attr[ATTR_VOLTAGE] = self._device.voltage
|
||||
|
||||
elif isinstance(self._device, Switch):
|
||||
for event in self.gateway.events:
|
||||
for event in self.hub.events:
|
||||
if self._device == event.device:
|
||||
attr[ATTR_EVENT_ID] = event.event_id
|
||||
|
||||
|
@ -426,13 +426,13 @@ class DeconzBatteryTracker:
|
|||
def __init__(
|
||||
self,
|
||||
sensor_id: str,
|
||||
gateway: DeconzHub,
|
||||
hub: DeconzHub,
|
||||
description: DeconzSensorDescription,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up tracker."""
|
||||
self.sensor = gateway.api.sensors[sensor_id]
|
||||
self.gateway = gateway
|
||||
self.sensor = hub.api.sensors[sensor_id]
|
||||
self.hub = hub
|
||||
self.description = description
|
||||
self.async_add_entities = async_add_entities
|
||||
self.unsubscribe = self.sensor.subscribe(self.async_update_callback)
|
||||
|
@ -443,5 +443,5 @@ class DeconzBatteryTracker:
|
|||
if self.description.update_key in self.sensor.changed_keys:
|
||||
self.unsubscribe()
|
||||
self.async_add_entities(
|
||||
[DeconzSensor(self.sensor, self.gateway, self.description)]
|
||||
[DeconzSensor(self.sensor, self.hub, self.description)]
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ from homeassistant.helpers.entity_registry import (
|
|||
)
|
||||
from homeassistant.util.read_only_dict import ReadOnlyDict
|
||||
|
||||
from .config_flow import get_master_gateway
|
||||
from .config_flow import get_master_hub
|
||||
from .const import CONF_BRIDGE_ID, DOMAIN, LOGGER
|
||||
from .hub import DeconzHub
|
||||
|
||||
|
@ -66,33 +66,33 @@ def async_setup_services(hass: HomeAssistant) -> None:
|
|||
service_data = service_call.data
|
||||
|
||||
if CONF_BRIDGE_ID in service_data:
|
||||
found_gateway = False
|
||||
found_hub = False
|
||||
bridge_id = normalize_bridge_id(service_data[CONF_BRIDGE_ID])
|
||||
|
||||
for possible_gateway in hass.data[DOMAIN].values():
|
||||
if possible_gateway.bridgeid == bridge_id:
|
||||
gateway = possible_gateway
|
||||
found_gateway = True
|
||||
for possible_hub in hass.data[DOMAIN].values():
|
||||
if possible_hub.bridgeid == bridge_id:
|
||||
hub = possible_hub
|
||||
found_hub = True
|
||||
break
|
||||
|
||||
if not found_gateway:
|
||||
if not found_hub:
|
||||
LOGGER.error("Could not find the gateway %s", bridge_id)
|
||||
return
|
||||
else:
|
||||
try:
|
||||
gateway = get_master_gateway(hass)
|
||||
hub = get_master_hub(hass)
|
||||
except ValueError:
|
||||
LOGGER.error("No master gateway available")
|
||||
return
|
||||
|
||||
if service == SERVICE_CONFIGURE_DEVICE:
|
||||
await async_configure_service(gateway, service_data)
|
||||
await async_configure_service(hub, service_data)
|
||||
|
||||
elif service == SERVICE_DEVICE_REFRESH:
|
||||
await async_refresh_devices_service(gateway)
|
||||
await async_refresh_devices_service(hub)
|
||||
|
||||
elif service == SERVICE_REMOVE_ORPHANED_ENTRIES:
|
||||
await async_remove_orphaned_entries_service(gateway)
|
||||
await async_remove_orphaned_entries_service(hub)
|
||||
|
||||
for service in SUPPORTED_SERVICES:
|
||||
hass.services.async_register(
|
||||
|
@ -110,7 +110,7 @@ def async_unload_services(hass: HomeAssistant) -> None:
|
|||
hass.services.async_remove(DOMAIN, service)
|
||||
|
||||
|
||||
async def async_configure_service(gateway: DeconzHub, data: ReadOnlyDict) -> None:
|
||||
async def async_configure_service(hub: DeconzHub, data: ReadOnlyDict) -> None:
|
||||
"""Set attribute of device in deCONZ.
|
||||
|
||||
Entity is used to resolve to a device path (e.g. '/lights/1').
|
||||
|
@ -132,61 +132,61 @@ async def async_configure_service(gateway: DeconzHub, data: ReadOnlyDict) -> Non
|
|||
|
||||
if entity_id:
|
||||
try:
|
||||
field = gateway.deconz_ids[entity_id] + field
|
||||
field = hub.deconz_ids[entity_id] + field
|
||||
except KeyError:
|
||||
LOGGER.error("Could not find the entity %s", entity_id)
|
||||
return
|
||||
|
||||
await gateway.api.request("put", field, json=data)
|
||||
await hub.api.request("put", field, json=data)
|
||||
|
||||
|
||||
async def async_refresh_devices_service(gateway: DeconzHub) -> None:
|
||||
async def async_refresh_devices_service(hub: DeconzHub) -> None:
|
||||
"""Refresh available devices from deCONZ."""
|
||||
gateway.ignore_state_updates = True
|
||||
await gateway.api.refresh_state()
|
||||
gateway.load_ignored_devices()
|
||||
gateway.ignore_state_updates = False
|
||||
hub.ignore_state_updates = True
|
||||
await hub.api.refresh_state()
|
||||
hub.load_ignored_devices()
|
||||
hub.ignore_state_updates = False
|
||||
|
||||
|
||||
async def async_remove_orphaned_entries_service(gateway: DeconzHub) -> None:
|
||||
async def async_remove_orphaned_entries_service(hub: DeconzHub) -> None:
|
||||
"""Remove orphaned deCONZ entries from device and entity registries."""
|
||||
device_registry = dr.async_get(gateway.hass)
|
||||
entity_registry = er.async_get(gateway.hass)
|
||||
device_registry = dr.async_get(hub.hass)
|
||||
entity_registry = er.async_get(hub.hass)
|
||||
|
||||
entity_entries = async_entries_for_config_entry(
|
||||
entity_registry, gateway.config_entry.entry_id
|
||||
entity_registry, hub.config_entry.entry_id
|
||||
)
|
||||
|
||||
entities_to_be_removed = []
|
||||
devices_to_be_removed = [
|
||||
entry.id
|
||||
for entry in device_registry.devices.values()
|
||||
if gateway.config_entry.entry_id in entry.config_entries
|
||||
if hub.config_entry.entry_id in entry.config_entries
|
||||
]
|
||||
|
||||
# Don't remove the Gateway host entry
|
||||
if gateway.api.config.mac:
|
||||
gateway_host = device_registry.async_get_device(
|
||||
connections={(CONNECTION_NETWORK_MAC, gateway.api.config.mac)},
|
||||
if hub.api.config.mac:
|
||||
hub_host = device_registry.async_get_device(
|
||||
connections={(CONNECTION_NETWORK_MAC, hub.api.config.mac)},
|
||||
)
|
||||
if gateway_host and gateway_host.id in devices_to_be_removed:
|
||||
devices_to_be_removed.remove(gateway_host.id)
|
||||
if hub_host and hub_host.id in devices_to_be_removed:
|
||||
devices_to_be_removed.remove(hub_host.id)
|
||||
|
||||
# Don't remove the Gateway service entry
|
||||
gateway_service = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, gateway.api.config.bridge_id)}
|
||||
hub_service = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, hub.api.config.bridge_id)}
|
||||
)
|
||||
if gateway_service and gateway_service.id in devices_to_be_removed:
|
||||
devices_to_be_removed.remove(gateway_service.id)
|
||||
if hub_service and hub_service.id in devices_to_be_removed:
|
||||
devices_to_be_removed.remove(hub_service.id)
|
||||
|
||||
# Don't remove devices belonging to available events
|
||||
for event in gateway.events:
|
||||
for event in hub.events:
|
||||
if event.device_id in devices_to_be_removed:
|
||||
devices_to_be_removed.remove(event.device_id)
|
||||
|
||||
for entry in entity_entries:
|
||||
# Don't remove available entities
|
||||
if entry.unique_id in gateway.entities[entry.domain]:
|
||||
if entry.unique_id in hub.entities[entry.domain]:
|
||||
# Don't remove devices with available entities
|
||||
if entry.device_id in devices_to_be_removed:
|
||||
devices_to_be_removed.remove(entry.device_id)
|
||||
|
|
|
@ -18,7 +18,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -27,18 +27,18 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up sirens for deCONZ component."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_siren(_: EventType, siren_id: str) -> None:
|
||||
"""Add siren from deCONZ."""
|
||||
siren = gateway.api.lights.sirens[siren_id]
|
||||
async_add_entities([DeconzSiren(siren, gateway)])
|
||||
siren = hub.api.lights.sirens[siren_id]
|
||||
async_add_entities([DeconzSiren(siren, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_siren,
|
||||
gateway.api.lights.sirens,
|
||||
hub.api.lights.sirens,
|
||||
)
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ class DeconzSiren(DeconzDevice[Siren], SirenEntity):
|
|||
"""Turn on siren."""
|
||||
if (duration := kwargs.get(ATTR_DURATION)) is not None:
|
||||
duration *= 10
|
||||
await self.gateway.api.lights.sirens.set_state(
|
||||
await self.hub.api.lights.sirens.set_state(
|
||||
id=self._device.resource_id,
|
||||
on=True,
|
||||
duration=duration,
|
||||
|
@ -69,7 +69,7 @@ class DeconzSiren(DeconzDevice[Siren], SirenEntity):
|
|||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off siren."""
|
||||
await self.gateway.api.lights.sirens.set_state(
|
||||
await self.hub.api.lights.sirens.set_state(
|
||||
id=self._device.resource_id,
|
||||
on=False,
|
||||
)
|
||||
|
|
|
@ -14,7 +14,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||
|
||||
from .const import POWER_PLUGS
|
||||
from .deconz_device import DeconzDevice
|
||||
from .hub import get_gateway_from_config_entry
|
||||
from .hub import DeconzHub
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -26,20 +26,20 @@ async def async_setup_entry(
|
|||
|
||||
Switches are based on the same device class as lights in deCONZ.
|
||||
"""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
hub = DeconzHub.get_hub(hass, config_entry)
|
||||
hub.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_switch(_: EventType, switch_id: str) -> None:
|
||||
"""Add switch from deCONZ."""
|
||||
switch = gateway.api.lights.lights[switch_id]
|
||||
switch = hub.api.lights.lights[switch_id]
|
||||
if switch.type not in POWER_PLUGS:
|
||||
return
|
||||
async_add_entities([DeconzPowerPlug(switch, gateway)])
|
||||
async_add_entities([DeconzPowerPlug(switch, hub)])
|
||||
|
||||
gateway.register_platform_add_device_callback(
|
||||
hub.register_platform_add_device_callback(
|
||||
async_add_switch,
|
||||
gateway.api.lights.lights,
|
||||
hub.api.lights.lights,
|
||||
)
|
||||
|
||||
|
||||
|
@ -55,14 +55,14 @@ class DeconzPowerPlug(DeconzDevice[Light], SwitchEntity):
|
|||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on switch."""
|
||||
await self.gateway.api.lights.lights.set_state(
|
||||
await self.hub.api.lights.lights.set_state(
|
||||
id=self._device.resource_id,
|
||||
on=True,
|
||||
)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off switch."""
|
||||
await self.gateway.api.lights.lights.set_state(
|
||||
await self.hub.api.lights.lights.set_state(
|
||||
id=self._device.resource_id,
|
||||
on=False,
|
||||
)
|
||||
|
|
|
@ -18,10 +18,7 @@ from homeassistant.components.cover import DOMAIN as COVER_DOMAIN
|
|||
from homeassistant.components.deconz.config_flow import DECONZ_MANUFACTURERURL
|
||||
from homeassistant.components.deconz.const import DOMAIN as DECONZ_DOMAIN
|
||||
from homeassistant.components.deconz.errors import AuthenticationRequired, CannotConnect
|
||||
from homeassistant.components.deconz.hub import (
|
||||
get_deconz_api,
|
||||
get_gateway_from_config_entry,
|
||||
)
|
||||
from homeassistant.components.deconz.hub import DeconzHub, get_deconz_api
|
||||
from homeassistant.components.fan import DOMAIN as FAN_DOMAIN
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN
|
||||
|
@ -149,7 +146,7 @@ async def test_gateway_setup(
|
|||
return_value=True,
|
||||
) as forward_entry_setup:
|
||||
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway = DeconzHub.get_hub(hass, config_entry)
|
||||
assert gateway.bridgeid == BRIDGEID
|
||||
assert gateway.master is True
|
||||
assert gateway.config.allow_clip_sensor is False
|
||||
|
@ -201,7 +198,7 @@ async def test_gateway_device_configuration_url_when_addon(
|
|||
config_entry = await setup_deconz_integration(
|
||||
hass, aioclient_mock, source=SOURCE_HASSIO
|
||||
)
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway = DeconzHub.get_hub(hass, config_entry)
|
||||
|
||||
gateway_entry = device_registry.async_get_device(
|
||||
identifiers={(DECONZ_DOMAIN, gateway.bridgeid)}
|
||||
|
@ -248,7 +245,7 @@ async def test_update_address(
|
|||
) -> None:
|
||||
"""Make sure that connection status triggers a dispatcher send."""
|
||||
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway = DeconzHub.get_hub(hass, config_entry)
|
||||
assert gateway.api.host == "1.2.3.4"
|
||||
|
||||
with patch(
|
||||
|
@ -280,7 +277,7 @@ async def test_reset_after_successful_setup(
|
|||
) -> None:
|
||||
"""Make sure that connection status triggers a dispatcher send."""
|
||||
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway = DeconzHub.get_hub(hass, config_entry)
|
||||
|
||||
result = await gateway.async_reset()
|
||||
await hass.async_block_till_done()
|
||||
|
|
Loading…
Add table
Reference in a new issue