Convert nexia to use entry.runtime_data (#121640)
parent
bf09cee66f
commit
6f15352eda
|
@ -7,7 +7,6 @@ from nexia.const import BRAND_NEXIA
|
|||
from nexia.home import NexiaHome
|
||||
from nexia.thermostat import NexiaThermostat
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
|
@ -17,6 +16,7 @@ import homeassistant.helpers.config_validation as cv
|
|||
|
||||
from .const import CONF_BRAND, DOMAIN, PLATFORMS
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .types import NexiaConfigEntry
|
||||
from .util import is_invalid_auth_code
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: NexiaConfigEntry) -> bool:
|
||||
"""Configure the base Nexia device for Home Assistant."""
|
||||
|
||||
conf = entry.data
|
||||
|
@ -63,26 +63,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
|
||||
coordinator = NexiaDataUpdateCoordinator(hass, nexia_home)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
||||
|
||||
entry.runtime_data = coordinator
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: NexiaConfigEntry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
return unload_ok
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
|
||||
async def async_remove_config_entry_device(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, device_entry: dr.DeviceEntry
|
||||
hass: HomeAssistant, entry: NexiaConfigEntry, device_entry: dr.DeviceEntry
|
||||
) -> bool:
|
||||
"""Remove a nexia config entry from a device."""
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
nexia_home: NexiaHome = coordinator.nexia_home
|
||||
coordinator = entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
dev_ids = {dev_id[1] for dev_id in device_entry.identifiers if dev_id[0] == DOMAIN}
|
||||
for thermostat_id in nexia_home.get_thermostat_ids():
|
||||
if thermostat_id in dev_ids:
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
"""Support for Nexia / Trane XL Thermostats."""
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .entity import NexiaThermostatEntity
|
||||
from .types import NexiaConfigEntry
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: NexiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up sensors for a Nexia device."""
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
coordinator = config_entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
|
||||
entities = []
|
||||
|
|
|
@ -15,7 +15,6 @@ from nexia.const import (
|
|||
SYSTEM_STATUS_HEAT,
|
||||
SYSTEM_STATUS_IDLE,
|
||||
)
|
||||
from nexia.home import NexiaHome
|
||||
from nexia.thermostat import NexiaThermostat
|
||||
from nexia.util import find_humidity_setpoint
|
||||
from nexia.zone import NexiaThermostatZone
|
||||
|
@ -31,7 +30,6 @@ from homeassistant.components.climate import (
|
|||
HVACAction,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_platform
|
||||
|
@ -44,10 +42,10 @@ from .const import (
|
|||
ATTR_DEHUMIDIFY_SETPOINT,
|
||||
ATTR_HUMIDIFY_SETPOINT,
|
||||
ATTR_RUN_MODE,
|
||||
DOMAIN,
|
||||
)
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .entity import NexiaThermostatZoneEntity
|
||||
from .types import NexiaConfigEntry
|
||||
from .util import percent_conv
|
||||
|
||||
PARALLEL_UPDATES = 1 # keep data in sync with only one connection at a time
|
||||
|
@ -116,12 +114,12 @@ NEXIA_SUPPORTED = (
|
|||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: NexiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up climate for a Nexia device."""
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
nexia_home: NexiaHome = coordinator.nexia_home
|
||||
coordinator = config_entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
|
||||
platform = entity_platform.async_get_current_platform()
|
||||
|
||||
|
@ -162,22 +160,23 @@ class NexiaZone(NexiaThermostatZoneEntity, ClimateEntity):
|
|||
) -> None:
|
||||
"""Initialize the thermostat."""
|
||||
super().__init__(coordinator, zone, zone.zone_id)
|
||||
unit = self._thermostat.get_unit()
|
||||
min_humidity, max_humidity = self._thermostat.get_humidity_setpoint_limits()
|
||||
min_setpoint, max_setpoint = self._thermostat.get_setpoint_limits()
|
||||
thermostat = self._thermostat
|
||||
unit = thermostat.get_unit()
|
||||
min_humidity, max_humidity = thermostat.get_humidity_setpoint_limits()
|
||||
min_setpoint, max_setpoint = thermostat.get_setpoint_limits()
|
||||
# The has_* calls are stable for the life of the device
|
||||
# and do not do I/O
|
||||
self._has_relative_humidity = self._thermostat.has_relative_humidity()
|
||||
self._has_emergency_heat = self._thermostat.has_emergency_heat()
|
||||
self._has_humidify_support = self._thermostat.has_humidify_support()
|
||||
self._has_dehumidify_support = self._thermostat.has_dehumidify_support()
|
||||
self._has_relative_humidity = thermostat.has_relative_humidity()
|
||||
self._has_emergency_heat = thermostat.has_emergency_heat()
|
||||
self._has_humidify_support = thermostat.has_humidify_support()
|
||||
self._has_dehumidify_support = thermostat.has_dehumidify_support()
|
||||
self._attr_supported_features = NEXIA_SUPPORTED
|
||||
if self._has_humidify_support or self._has_dehumidify_support:
|
||||
self._attr_supported_features |= ClimateEntityFeature.TARGET_HUMIDITY
|
||||
if self._has_emergency_heat:
|
||||
self._attr_supported_features |= ClimateEntityFeature.AUX_HEAT
|
||||
self._attr_preset_modes = self._zone.get_presets()
|
||||
self._attr_fan_modes = self._thermostat.get_fan_modes()
|
||||
self._attr_preset_modes = zone.get_presets()
|
||||
self._attr_fan_modes = thermostat.get_fan_modes()
|
||||
self._attr_hvac_modes = HVAC_MODES
|
||||
self._attr_min_humidity = percent_conv(min_humidity)
|
||||
self._attr_max_humidity = percent_conv(max_humidity)
|
||||
|
|
|
@ -5,11 +5,10 @@ from __future__ import annotations
|
|||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .const import CONF_BRAND, DOMAIN
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .const import CONF_BRAND
|
||||
from .types import NexiaConfigEntry
|
||||
|
||||
TO_REDACT = {
|
||||
"dealer_contact_info",
|
||||
|
@ -17,10 +16,10 @@ TO_REDACT = {
|
|||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
hass: HomeAssistant, entry: NexiaConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
coordinator = entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""The nexia integration base entity."""
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from nexia.thermostat import NexiaThermostat
|
||||
from nexia.zone import NexiaThermostatZone
|
||||
|
||||
|
@ -42,31 +44,38 @@ class NexiaThermostatEntity(NexiaEntity):
|
|||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(self, coordinator, thermostat, unique_id):
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: NexiaDataUpdateCoordinator,
|
||||
thermostat: NexiaThermostat,
|
||||
unique_id: str,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
super().__init__(coordinator, unique_id)
|
||||
self._thermostat: NexiaThermostat = thermostat
|
||||
self._thermostat = thermostat
|
||||
thermostat_id = thermostat.thermostat_id
|
||||
self._attr_device_info = DeviceInfo(
|
||||
configuration_url=self.coordinator.nexia_home.root_url,
|
||||
identifiers={(DOMAIN, self._thermostat.thermostat_id)},
|
||||
identifiers={(DOMAIN, thermostat_id)},
|
||||
manufacturer=MANUFACTURER,
|
||||
model=self._thermostat.get_model(),
|
||||
name=self._thermostat.get_name(),
|
||||
sw_version=self._thermostat.get_firmware(),
|
||||
model=thermostat.get_model(),
|
||||
name=thermostat.get_name(),
|
||||
sw_version=thermostat.get_firmware(),
|
||||
)
|
||||
self._thermostat_signal = f"{SIGNAL_THERMOSTAT_UPDATE}-{thermostat_id}"
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Listen for signals for services."""
|
||||
await super().async_added_to_hass()
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
f"{SIGNAL_THERMOSTAT_UPDATE}-{self._thermostat.thermostat_id}",
|
||||
self._thermostat_signal,
|
||||
self.async_write_ha_state,
|
||||
)
|
||||
)
|
||||
|
||||
def _signal_thermostat_update(self):
|
||||
def _signal_thermostat_update(self) -> None:
|
||||
"""Signal a thermostat update.
|
||||
|
||||
Whenever the underlying library does an action against
|
||||
|
@ -75,9 +84,7 @@ class NexiaThermostatEntity(NexiaEntity):
|
|||
|
||||
Update all the zones on the thermostat.
|
||||
"""
|
||||
async_dispatcher_send(
|
||||
self.hass, f"{SIGNAL_THERMOSTAT_UPDATE}-{self._thermostat.thermostat_id}"
|
||||
)
|
||||
async_dispatcher_send(self.hass, self._thermostat_signal)
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
|
@ -88,30 +95,38 @@ class NexiaThermostatEntity(NexiaEntity):
|
|||
class NexiaThermostatZoneEntity(NexiaThermostatEntity):
|
||||
"""Base class for nexia devices attached to a thermostat."""
|
||||
|
||||
def __init__(self, coordinator, zone, unique_id):
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: NexiaDataUpdateCoordinator,
|
||||
zone: NexiaThermostatZone,
|
||||
unique_id: str,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
super().__init__(coordinator, zone.thermostat, unique_id)
|
||||
self._zone: NexiaThermostatZone = zone
|
||||
self._zone = zone
|
||||
zone_name = self._zone.get_name()
|
||||
if TYPE_CHECKING:
|
||||
assert self._attr_device_info is not None
|
||||
self._attr_device_info |= {
|
||||
ATTR_IDENTIFIERS: {(DOMAIN, self._zone.zone_id)},
|
||||
ATTR_IDENTIFIERS: {(DOMAIN, zone.zone_id)},
|
||||
ATTR_NAME: zone_name,
|
||||
ATTR_SUGGESTED_AREA: zone_name,
|
||||
ATTR_VIA_DEVICE: (DOMAIN, self._zone.thermostat.thermostat_id),
|
||||
ATTR_VIA_DEVICE: (DOMAIN, zone.thermostat.thermostat_id),
|
||||
}
|
||||
self._zone_signal = f"{SIGNAL_ZONE_UPDATE}-{zone.zone_id}"
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Listen for signals for services."""
|
||||
await super().async_added_to_hass()
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
f"{SIGNAL_ZONE_UPDATE}-{self._zone.zone_id}",
|
||||
self._zone_signal,
|
||||
self.async_write_ha_state,
|
||||
)
|
||||
)
|
||||
|
||||
def _signal_zone_update(self):
|
||||
def _signal_zone_update(self) -> None:
|
||||
"""Signal a zone update.
|
||||
|
||||
Whenever the underlying library does an action against
|
||||
|
@ -119,4 +134,4 @@ class NexiaThermostatZoneEntity(NexiaThermostatEntity):
|
|||
|
||||
Update a single zone.
|
||||
"""
|
||||
async_dispatcher_send(self.hass, f"{SIGNAL_ZONE_UPDATE}-{self._zone.zone_id}")
|
||||
async_dispatcher_send(self.hass, self._zone_signal)
|
||||
|
|
|
@ -2,29 +2,27 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from nexia.home import NexiaHome
|
||||
from nexia.thermostat import NexiaThermostat
|
||||
|
||||
from homeassistant.components.number import NumberEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import PERCENTAGE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .entity import NexiaThermostatEntity
|
||||
from .types import NexiaConfigEntry
|
||||
from .util import percent_conv
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: NexiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up sensors for a Nexia device."""
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
nexia_home: NexiaHome = coordinator.nexia_home
|
||||
coordinator = config_entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
|
||||
entities: list[NexiaThermostatEntity] = []
|
||||
for thermostat_id in nexia_home.get_thermostat_ids():
|
||||
|
|
|
@ -5,25 +5,25 @@ from typing import Any
|
|||
from nexia.automation import NexiaAutomation
|
||||
|
||||
from homeassistant.components.scene import Scene
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
|
||||
from .const import ATTR_DESCRIPTION, DOMAIN
|
||||
from .const import ATTR_DESCRIPTION
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .entity import NexiaEntity
|
||||
from .types import NexiaConfigEntry
|
||||
|
||||
SCENE_ACTIVATION_TIME = 5
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: NexiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up automations for a Nexia device."""
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
coordinator = config_entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
async_add_entities(
|
||||
NexiaAutomationScene(
|
||||
|
@ -42,12 +42,9 @@ class NexiaAutomationScene(NexiaEntity, Scene):
|
|||
self, coordinator: NexiaDataUpdateCoordinator, automation: NexiaAutomation
|
||||
) -> None:
|
||||
"""Initialize the automation scene."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
automation.automation_id,
|
||||
)
|
||||
super().__init__(coordinator, automation.automation_id)
|
||||
self._attr_name = automation.name
|
||||
self._automation: NexiaAutomation = automation
|
||||
self._automation = automation
|
||||
self._attr_extra_state_attributes = {ATTR_DESCRIPTION: automation.description}
|
||||
|
||||
async def async_activate(self, **kwargs: Any) -> None:
|
||||
|
|
|
@ -10,25 +10,23 @@ from homeassistant.components.sensor import (
|
|||
SensorEntity,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import PERCENTAGE, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .entity import NexiaThermostatEntity, NexiaThermostatZoneEntity
|
||||
from .types import NexiaConfigEntry
|
||||
from .util import percent_conv
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: NexiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up sensors for a Nexia device."""
|
||||
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
coordinator = config_entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
entities: list[NexiaThermostatEntity] = []
|
||||
|
||||
|
|
|
@ -5,28 +5,26 @@ from __future__ import annotations
|
|||
from typing import Any
|
||||
|
||||
from nexia.const import OPERATION_MODE_OFF
|
||||
from nexia.home import NexiaHome
|
||||
from nexia.thermostat import NexiaThermostat
|
||||
from nexia.zone import NexiaThermostatZone
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
from .entity import NexiaThermostatZoneEntity
|
||||
from .types import NexiaConfigEntry
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: NexiaConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up switches for a Nexia device."""
|
||||
coordinator: NexiaDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
nexia_home: NexiaHome = coordinator.nexia_home
|
||||
coordinator = config_entry.runtime_data
|
||||
nexia_home = coordinator.nexia_home
|
||||
entities: list[NexiaHoldSwitch] = []
|
||||
for thermostat_id in nexia_home.get_thermostat_ids():
|
||||
thermostat: NexiaThermostat = nexia_home.get_thermostat_by_id(thermostat_id)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
"""Support for Nexia / Trane XL Thermostats."""
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
||||
from .coordinator import NexiaDataUpdateCoordinator
|
||||
|
||||
type NexiaConfigEntry = ConfigEntry[NexiaDataUpdateCoordinator]
|
Loading…
Reference in New Issue