mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 22:07:10 +00:00
Migrate elkm1 to use a dataclass for integration data (#99830)
* Migrate elkm1 to use a dataclass for integration data * fix unsaved * slotted * missing coveragerc * Revert "missing coveragerc" This reverts commit 3397b40309033276d20fef59098b0a1b5b681a30.
This commit is contained in:
parent
3d403c9b60
commit
d624bbbc0c
@ -2,11 +2,12 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from collections.abc import Iterable
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from types import MappingProxyType
|
from types import MappingProxyType
|
||||||
from typing import Any, cast
|
from typing import Any
|
||||||
|
|
||||||
from elkm1_lib.elements import Element
|
from elkm1_lib.elements import Element
|
||||||
from elkm1_lib.elk import Elk
|
from elkm1_lib.elk import Elk
|
||||||
@ -65,6 +66,7 @@ from .discovery import (
|
|||||||
async_trigger_discovery,
|
async_trigger_discovery,
|
||||||
async_update_entry_from_discovery,
|
async_update_entry_from_discovery,
|
||||||
)
|
)
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
SYNC_TIMEOUT = 120
|
SYNC_TIMEOUT = 120
|
||||||
|
|
||||||
@ -303,14 +305,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
else:
|
else:
|
||||||
temperature_unit = UnitOfTemperature.FAHRENHEIT
|
temperature_unit = UnitOfTemperature.FAHRENHEIT
|
||||||
config["temperature_unit"] = temperature_unit
|
config["temperature_unit"] = temperature_unit
|
||||||
hass.data[DOMAIN][entry.entry_id] = {
|
prefix: str = conf[CONF_PREFIX]
|
||||||
"elk": elk,
|
auto_configure: bool = conf[CONF_AUTO_CONFIGURE]
|
||||||
"prefix": conf[CONF_PREFIX],
|
hass.data[DOMAIN][entry.entry_id] = ELKM1Data(
|
||||||
"mac": entry.unique_id,
|
elk=elk,
|
||||||
"auto_configure": conf[CONF_AUTO_CONFIGURE],
|
prefix=prefix,
|
||||||
"config": config,
|
mac=entry.unique_id,
|
||||||
"keypads": {},
|
auto_configure=auto_configure,
|
||||||
}
|
config=config,
|
||||||
|
keypads={},
|
||||||
|
)
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
|
||||||
@ -326,21 +330,23 @@ def _included(ranges: list[tuple[int, int]], set_to: bool, values: list[bool]) -
|
|||||||
|
|
||||||
def _find_elk_by_prefix(hass: HomeAssistant, prefix: str) -> Elk | None:
|
def _find_elk_by_prefix(hass: HomeAssistant, prefix: str) -> Elk | None:
|
||||||
"""Search all config entries for a given prefix."""
|
"""Search all config entries for a given prefix."""
|
||||||
for entry_id in hass.data[DOMAIN]:
|
all_elk: dict[str, ELKM1Data] = hass.data[DOMAIN]
|
||||||
if hass.data[DOMAIN][entry_id]["prefix"] == prefix:
|
for elk_data in all_elk.values():
|
||||||
return cast(Elk, hass.data[DOMAIN][entry_id]["elk"])
|
if elk_data.prefix == prefix:
|
||||||
|
return elk_data.elk
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
all_elk: dict[str, ELKM1Data] = hass.data[DOMAIN]
|
||||||
|
|
||||||
# disconnect cleanly
|
# disconnect cleanly
|
||||||
hass.data[DOMAIN][entry.entry_id]["elk"].disconnect()
|
all_elk[entry.entry_id].elk.disconnect()
|
||||||
|
|
||||||
if unload_ok:
|
if unload_ok:
|
||||||
hass.data[DOMAIN].pop(entry.entry_id)
|
all_elk.pop(entry.entry_id)
|
||||||
|
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
@ -421,19 +427,19 @@ def _create_elk_services(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def create_elk_entities(
|
def create_elk_entities(
|
||||||
elk_data: dict[str, Any],
|
elk_data: ELKM1Data,
|
||||||
elk_elements: list[Element],
|
elk_elements: Iterable[Element],
|
||||||
element_type: str,
|
element_type: str,
|
||||||
class_: Any,
|
class_: Any,
|
||||||
entities: list[ElkEntity],
|
entities: list[ElkEntity],
|
||||||
) -> list[ElkEntity] | None:
|
) -> list[ElkEntity] | None:
|
||||||
"""Create the ElkM1 devices of a particular class."""
|
"""Create the ElkM1 devices of a particular class."""
|
||||||
auto_configure = elk_data["auto_configure"]
|
auto_configure = elk_data.auto_configure
|
||||||
|
|
||||||
if not auto_configure and not elk_data["config"][element_type]["enabled"]:
|
if not auto_configure and not elk_data.config[element_type]["enabled"]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
elk = elk_data["elk"]
|
elk = elk_data.elk
|
||||||
_LOGGER.debug("Creating elk entities for %s", elk)
|
_LOGGER.debug("Creating elk entities for %s", elk)
|
||||||
|
|
||||||
for element in elk_elements:
|
for element in elk_elements:
|
||||||
@ -441,7 +447,7 @@ def create_elk_entities(
|
|||||||
if not element.configured:
|
if not element.configured:
|
||||||
continue
|
continue
|
||||||
# Only check the included list if auto configure is not
|
# Only check the included list if auto configure is not
|
||||||
elif not elk_data["config"][element_type]["included"][element.index]:
|
elif not elk_data.config[element_type]["included"][element.index]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
entities.append(class_(element, elk, elk_data))
|
entities.append(class_(element, elk, elk_data))
|
||||||
@ -454,13 +460,13 @@ class ElkEntity(Entity):
|
|||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
|
||||||
def __init__(self, element: Element, elk: Elk, elk_data: dict[str, Any]) -> None:
|
def __init__(self, element: Element, elk: Elk, elk_data: ELKM1Data) -> None:
|
||||||
"""Initialize the base of all Elk devices."""
|
"""Initialize the base of all Elk devices."""
|
||||||
self._elk = elk
|
self._elk = elk
|
||||||
self._element = element
|
self._element = element
|
||||||
self._mac = elk_data["mac"]
|
self._mac = elk_data.mac
|
||||||
self._prefix = elk_data["prefix"]
|
self._prefix = elk_data.prefix
|
||||||
self._temperature_unit: str = elk_data["config"]["temperature_unit"]
|
self._temperature_unit: str = elk_data.config["temperature_unit"]
|
||||||
# unique_id starts with elkm1_ iff there is no prefix
|
# unique_id starts with elkm1_ iff there is no prefix
|
||||||
# it starts with elkm1m_{prefix} iff there is a prefix
|
# it starts with elkm1m_{prefix} iff there is a prefix
|
||||||
# this is to avoid a conflict between
|
# this is to avoid a conflict between
|
||||||
@ -496,9 +502,7 @@ class ElkEntity(Entity):
|
|||||||
|
|
||||||
def initial_attrs(self) -> dict[str, Any]:
|
def initial_attrs(self) -> dict[str, Any]:
|
||||||
"""Return the underlying element's attributes as a dict."""
|
"""Return the underlying element's attributes as a dict."""
|
||||||
attrs = {}
|
return {"index": self._element.index + 1}
|
||||||
attrs["index"] = self._element.index + 1
|
|
||||||
return attrs
|
|
||||||
|
|
||||||
def _element_changed(self, element: Element, changeset: dict[str, Any]) -> None:
|
def _element_changed(self, element: Element, changeset: dict[str, Any]) -> None:
|
||||||
pass
|
pass
|
||||||
|
@ -40,6 +40,7 @@ from .const import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
ELK_USER_CODE_SERVICE_SCHEMA,
|
ELK_USER_CODE_SERVICE_SCHEMA,
|
||||||
)
|
)
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
DISPLAY_MESSAGE_SERVICE_SCHEMA = {
|
DISPLAY_MESSAGE_SERVICE_SCHEMA = {
|
||||||
vol.Optional("clear", default=2): vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
|
vol.Optional("clear", default=2): vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
|
||||||
@ -65,8 +66,9 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the ElkM1 alarm platform."""
|
"""Set up the ElkM1 alarm platform."""
|
||||||
elk_data = hass.data[DOMAIN][config_entry.entry_id]
|
|
||||||
elk = elk_data["elk"]
|
elk_data: ELKM1Data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
elk = elk_data.elk
|
||||||
entities: list[ElkEntity] = []
|
entities: list[ElkEntity] = []
|
||||||
create_elk_entities(elk_data, elk.areas, "area", ElkArea, entities)
|
create_elk_entities(elk_data, elk.areas, "area", ElkArea, entities)
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
@ -115,7 +117,7 @@ class ElkArea(ElkAttachedEntity, AlarmControlPanelEntity, RestoreEntity):
|
|||||||
)
|
)
|
||||||
_element: Area
|
_element: Area
|
||||||
|
|
||||||
def __init__(self, element: Element, elk: Elk, elk_data: dict[str, Any]) -> None:
|
def __init__(self, element: Element, elk: Elk, elk_data: ELKM1Data) -> None:
|
||||||
"""Initialize Area as Alarm Control Panel."""
|
"""Initialize Area as Alarm Control Panel."""
|
||||||
super().__init__(element, elk, elk_data)
|
super().__init__(element, elk, elk_data)
|
||||||
self._elk = elk
|
self._elk = elk
|
||||||
|
@ -14,6 +14,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import ElkAttachedEntity, ElkEntity
|
from . import ElkAttachedEntity, ElkEntity
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
@ -22,21 +23,20 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the Elk-M1 sensor platform."""
|
"""Create the Elk-M1 sensor platform."""
|
||||||
|
elk_data: ELKM1Data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
elk_data = hass.data[DOMAIN][config_entry.entry_id]
|
elk = elk_data.elk
|
||||||
auto_configure = elk_data["auto_configure"]
|
auto_configure = elk_data.auto_configure
|
||||||
elk = elk_data["elk"]
|
|
||||||
|
|
||||||
entities: list[ElkEntity] = []
|
entities: list[ElkEntity] = []
|
||||||
for element in elk.zones:
|
for element in elk.zones:
|
||||||
# Don't create binary sensors for zones that are analog
|
# Don't create binary sensors for zones that are analog
|
||||||
if element.definition in {ZoneType.TEMPERATURE, ZoneType.ANALOG_ZONE}:
|
if element.definition in {ZoneType.TEMPERATURE, ZoneType.ANALOG_ZONE}: # type: ignore[attr-defined]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if auto_configure:
|
if auto_configure:
|
||||||
if not element.configured:
|
if not element.configured:
|
||||||
continue
|
continue
|
||||||
elif not elk_data["config"]["zone"]["included"][element.index]:
|
elif not elk_data.config["zone"]["included"][element.index]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
entities.append(ElkBinarySensor(element, elk, elk_data))
|
entities.append(ElkBinarySensor(element, elk, elk_data))
|
||||||
|
@ -23,6 +23,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import ElkEntity, create_elk_entities
|
from . import ElkEntity, create_elk_entities
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
SUPPORT_HVAC = [
|
SUPPORT_HVAC = [
|
||||||
HVACMode.OFF,
|
HVACMode.OFF,
|
||||||
@ -61,9 +62,9 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the Elk-M1 thermostat platform."""
|
"""Create the Elk-M1 thermostat platform."""
|
||||||
elk_data = hass.data[DOMAIN][config_entry.entry_id]
|
elk_data: ELKM1Data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
elk = elk_data.elk
|
||||||
entities: list[ElkEntity] = []
|
entities: list[ElkEntity] = []
|
||||||
elk = elk_data["elk"]
|
|
||||||
create_elk_entities(
|
create_elk_entities(
|
||||||
elk_data, elk.thermostats, "thermostat", ElkThermostat, entities
|
elk_data, elk.thermostats, "thermostat", ElkThermostat, entities
|
||||||
)
|
)
|
||||||
|
@ -14,6 +14,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import ElkEntity, create_elk_entities
|
from . import ElkEntity, create_elk_entities
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
@ -22,9 +23,9 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Elk light platform."""
|
"""Set up the Elk light platform."""
|
||||||
elk_data = hass.data[DOMAIN][config_entry.entry_id]
|
elk_data: ELKM1Data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
elk = elk_data.elk
|
||||||
entities: list[ElkEntity] = []
|
entities: list[ElkEntity] = []
|
||||||
elk = elk_data["elk"]
|
|
||||||
create_elk_entities(elk_data, elk.lights, "plc", ElkLight, entities)
|
create_elk_entities(elk_data, elk.lights, "plc", ElkLight, entities)
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ class ElkLight(ElkEntity, LightEntity):
|
|||||||
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
||||||
_element: Light
|
_element: Light
|
||||||
|
|
||||||
def __init__(self, element: Element, elk: Elk, elk_data: dict[str, Any]) -> None:
|
def __init__(self, element: Element, elk: Elk, elk_data: ELKM1Data) -> None:
|
||||||
"""Initialize the Elk light."""
|
"""Initialize the Elk light."""
|
||||||
super().__init__(element, elk, elk_data)
|
super().__init__(element, elk, elk_data)
|
||||||
self._brightness = self._element.status
|
self._brightness = self._element.status
|
||||||
|
19
homeassistant/components/elkm1/models.py
Normal file
19
homeassistant/components/elkm1/models.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
"""The elkm1 integration models."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from elkm1_lib import Elk
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(slots=True)
|
||||||
|
class ELKM1Data:
|
||||||
|
"""Data for the elkm1 integration."""
|
||||||
|
|
||||||
|
elk: Elk
|
||||||
|
prefix: str
|
||||||
|
mac: str | None
|
||||||
|
auto_configure: bool
|
||||||
|
config: dict[str, Any]
|
||||||
|
keypads: dict[str, Any]
|
@ -12,6 +12,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import ElkAttachedEntity, ElkEntity, create_elk_entities
|
from . import ElkAttachedEntity, ElkEntity, create_elk_entities
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
@ -20,9 +21,9 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the Elk-M1 scene platform."""
|
"""Create the Elk-M1 scene platform."""
|
||||||
elk_data = hass.data[DOMAIN][config_entry.entry_id]
|
elk_data: ELKM1Data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
elk = elk_data.elk
|
||||||
entities: list[ElkEntity] = []
|
entities: list[ElkEntity] = []
|
||||||
elk = elk_data["elk"]
|
|
||||||
create_elk_entities(elk_data, elk.tasks, "task", ElkTask, entities)
|
create_elk_entities(elk_data, elk.tasks, "task", ElkTask, entities)
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import ElkAttachedEntity, ElkEntity, create_elk_entities
|
from . import ElkAttachedEntity, ElkEntity, create_elk_entities
|
||||||
from .const import ATTR_VALUE, DOMAIN, ELK_USER_CODE_SERVICE_SCHEMA
|
from .const import ATTR_VALUE, DOMAIN, ELK_USER_CODE_SERVICE_SCHEMA
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
SERVICE_SENSOR_COUNTER_REFRESH = "sensor_counter_refresh"
|
SERVICE_SENSOR_COUNTER_REFRESH = "sensor_counter_refresh"
|
||||||
SERVICE_SENSOR_COUNTER_SET = "sensor_counter_set"
|
SERVICE_SENSOR_COUNTER_SET = "sensor_counter_set"
|
||||||
@ -41,9 +42,9 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the Elk-M1 sensor platform."""
|
"""Create the Elk-M1 sensor platform."""
|
||||||
elk_data = hass.data[DOMAIN][config_entry.entry_id]
|
elk_data: ELKM1Data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
elk = elk_data.elk
|
||||||
entities: list[ElkEntity] = []
|
entities: list[ElkEntity] = []
|
||||||
elk = elk_data["elk"]
|
|
||||||
create_elk_entities(elk_data, elk.counters, "counter", ElkCounter, entities)
|
create_elk_entities(elk_data, elk.counters, "counter", ElkCounter, entities)
|
||||||
create_elk_entities(elk_data, elk.keypads, "keypad", ElkKeypad, entities)
|
create_elk_entities(elk_data, elk.keypads, "keypad", ElkKeypad, entities)
|
||||||
create_elk_entities(elk_data, [elk.panel], "panel", ElkPanel, entities)
|
create_elk_entities(elk_data, [elk.panel], "panel", ElkPanel, entities)
|
||||||
|
@ -12,6 +12,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
|
|
||||||
from . import ElkAttachedEntity, ElkEntity, create_elk_entities
|
from . import ElkAttachedEntity, ElkEntity, create_elk_entities
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
from .models import ELKM1Data
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
@ -20,9 +21,9 @@ async def async_setup_entry(
|
|||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the Elk-M1 switch platform."""
|
"""Create the Elk-M1 switch platform."""
|
||||||
elk_data = hass.data[DOMAIN][config_entry.entry_id]
|
elk_data: ELKM1Data = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
elk = elk_data.elk
|
||||||
entities: list[ElkEntity] = []
|
entities: list[ElkEntity] = []
|
||||||
elk = elk_data["elk"]
|
|
||||||
create_elk_entities(elk_data, elk.outputs, "output", ElkOutput, entities)
|
create_elk_entities(elk_data, elk.outputs, "output", ElkOutput, entities)
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user