mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Migrate lcn to use runtime_data (#147333)
This commit is contained in:
parent
2bfb09cb11
commit
d06da8c2da
@ -16,7 +16,6 @@ from pypck.connection import (
|
|||||||
)
|
)
|
||||||
from pypck.lcn_defs import LcnEvent
|
from pypck.lcn_defs import LcnEvent
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_DEVICE_ID,
|
CONF_DEVICE_ID,
|
||||||
CONF_DOMAIN,
|
CONF_DOMAIN,
|
||||||
@ -38,21 +37,20 @@ from homeassistant.helpers import (
|
|||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_ACKNOWLEDGE,
|
CONF_ACKNOWLEDGE,
|
||||||
CONF_DIM_MODE,
|
CONF_DIM_MODE,
|
||||||
CONF_DOMAIN_DATA,
|
CONF_DOMAIN_DATA,
|
||||||
CONF_SK_NUM_TRIES,
|
CONF_SK_NUM_TRIES,
|
||||||
CONF_TARGET_VALUE_LOCKED,
|
CONF_TARGET_VALUE_LOCKED,
|
||||||
CONF_TRANSITION,
|
CONF_TRANSITION,
|
||||||
CONNECTION,
|
|
||||||
DEVICE_CONNECTIONS,
|
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
PLATFORMS,
|
PLATFORMS,
|
||||||
)
|
)
|
||||||
from .helpers import (
|
from .helpers import (
|
||||||
AddressType,
|
AddressType,
|
||||||
InputType,
|
InputType,
|
||||||
|
LcnConfigEntry,
|
||||||
|
LcnRuntimeData,
|
||||||
async_update_config_entry,
|
async_update_config_entry,
|
||||||
generate_unique_id,
|
generate_unique_id,
|
||||||
purge_device_registry,
|
purge_device_registry,
|
||||||
@ -69,18 +67,14 @@ CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
|||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
"""Set up the LCN component."""
|
"""Set up the LCN component."""
|
||||||
hass.data.setdefault(DOMAIN, {})
|
|
||||||
|
|
||||||
async_setup_services(hass)
|
async_setup_services(hass)
|
||||||
await register_panel_and_ws_api(hass)
|
await register_panel_and_ws_api(hass)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, config_entry: LcnConfigEntry) -> bool:
|
||||||
"""Set up a connection to PCHK host from a config entry."""
|
"""Set up a connection to PCHK host from a config entry."""
|
||||||
if config_entry.entry_id in hass.data[DOMAIN]:
|
|
||||||
return False
|
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
"SK_NUM_TRIES": config_entry.data[CONF_SK_NUM_TRIES],
|
"SK_NUM_TRIES": config_entry.data[CONF_SK_NUM_TRIES],
|
||||||
@ -114,11 +108,11 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||||||
) from ex
|
) from ex
|
||||||
|
|
||||||
_LOGGER.debug('LCN connected to "%s"', config_entry.title)
|
_LOGGER.debug('LCN connected to "%s"', config_entry.title)
|
||||||
hass.data[DOMAIN][config_entry.entry_id] = {
|
config_entry.runtime_data = LcnRuntimeData(
|
||||||
CONNECTION: lcn_connection,
|
connection=lcn_connection,
|
||||||
DEVICE_CONNECTIONS: {},
|
device_connections={},
|
||||||
ADD_ENTITIES_CALLBACKS: {},
|
add_entities_callbacks={},
|
||||||
}
|
)
|
||||||
|
|
||||||
# Update config_entry with LCN device serials
|
# Update config_entry with LCN device serials
|
||||||
await async_update_config_entry(hass, config_entry)
|
await async_update_config_entry(hass, config_entry)
|
||||||
@ -146,7 +140,9 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
async def async_migrate_entry(
|
||||||
|
hass: HomeAssistant, config_entry: LcnConfigEntry
|
||||||
|
) -> bool:
|
||||||
"""Migrate old entry."""
|
"""Migrate old entry."""
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Migrating configuration from version %s.%s",
|
"Migrating configuration from version %s.%s",
|
||||||
@ -195,7 +191,7 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
|||||||
|
|
||||||
|
|
||||||
async def async_migrate_entities(
|
async def async_migrate_entities(
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry
|
hass: HomeAssistant, config_entry: LcnConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Migrate entity registry."""
|
"""Migrate entity registry."""
|
||||||
|
|
||||||
@ -217,25 +213,24 @@ async def async_migrate_entities(
|
|||||||
await er.async_migrate_entries(hass, config_entry.entry_id, update_unique_id)
|
await er.async_migrate_entries(hass, config_entry.entry_id, update_unique_id)
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, config_entry: LcnConfigEntry) -> bool:
|
||||||
"""Close connection to PCHK host represented by config_entry."""
|
"""Close connection to PCHK host represented by config_entry."""
|
||||||
# forward unloading to platforms
|
# forward unloading to platforms
|
||||||
unload_ok = await hass.config_entries.async_unload_platforms(
|
unload_ok = await hass.config_entries.async_unload_platforms(
|
||||||
config_entry, PLATFORMS
|
config_entry, PLATFORMS
|
||||||
)
|
)
|
||||||
|
|
||||||
if unload_ok and config_entry.entry_id in hass.data[DOMAIN]:
|
if unload_ok:
|
||||||
host = hass.data[DOMAIN].pop(config_entry.entry_id)
|
await config_entry.runtime_data.connection.async_close()
|
||||||
await host[CONNECTION].async_close()
|
|
||||||
|
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
def async_host_event_received(
|
def async_host_event_received(
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry, event: pypck.lcn_defs.LcnEvent
|
hass: HomeAssistant, config_entry: LcnConfigEntry, event: pypck.lcn_defs.LcnEvent
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Process received event from LCN."""
|
"""Process received event from LCN."""
|
||||||
lcn_connection = hass.data[DOMAIN][config_entry.entry_id][CONNECTION]
|
lcn_connection = config_entry.runtime_data.connection
|
||||||
|
|
||||||
async def reload_config_entry() -> None:
|
async def reload_config_entry() -> None:
|
||||||
"""Close connection and schedule config entry for reload."""
|
"""Close connection and schedule config entry for reload."""
|
||||||
@ -258,7 +253,7 @@ def async_host_event_received(
|
|||||||
|
|
||||||
def async_host_input_received(
|
def async_host_input_received(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
device_registry: dr.DeviceRegistry,
|
device_registry: dr.DeviceRegistry,
|
||||||
inp: pypck.inputs.Input,
|
inp: pypck.inputs.Input,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -266,7 +261,7 @@ def async_host_input_received(
|
|||||||
if not isinstance(inp, pypck.inputs.ModInput):
|
if not isinstance(inp, pypck.inputs.ModInput):
|
||||||
return
|
return
|
||||||
|
|
||||||
lcn_connection = hass.data[DOMAIN][config_entry.entry_id][CONNECTION]
|
lcn_connection = config_entry.runtime_data.connection
|
||||||
logical_address = lcn_connection.physical_to_logical(inp.physical_source_addr)
|
logical_address = lcn_connection.physical_to_logical(inp.physical_source_addr)
|
||||||
address = (
|
address = (
|
||||||
logical_address.seg_id,
|
logical_address.seg_id,
|
||||||
|
@ -11,7 +11,6 @@ from homeassistant.components.binary_sensor import (
|
|||||||
BinarySensorEntity,
|
BinarySensorEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.components.script import scripts_with_entity
|
from homeassistant.components.script import scripts_with_entity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES, CONF_SOURCE
|
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES, CONF_SOURCE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
@ -22,19 +21,13 @@ from homeassistant.helpers.issue_registry import (
|
|||||||
)
|
)
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import BINSENSOR_PORTS, CONF_DOMAIN_DATA, DOMAIN, SETPOINTS
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
BINSENSOR_PORTS,
|
|
||||||
CONF_DOMAIN_DATA,
|
|
||||||
DOMAIN,
|
|
||||||
SETPOINTS,
|
|
||||||
)
|
|
||||||
from .entity import LcnEntity
|
from .entity import LcnEntity
|
||||||
from .helpers import InputType
|
from .helpers import InputType, LcnConfigEntry
|
||||||
|
|
||||||
|
|
||||||
def add_lcn_entities(
|
def add_lcn_entities(
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
entity_configs: Iterable[ConfigType],
|
entity_configs: Iterable[ConfigType],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -53,7 +46,7 @@ def add_lcn_entities(
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up LCN switch entities from a config entry."""
|
"""Set up LCN switch entities from a config entry."""
|
||||||
@ -63,7 +56,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities,
|
async_add_entities,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
|
config_entry.runtime_data.add_entities_callbacks.update(
|
||||||
{DOMAIN_BINARY_SENSOR: add_entities}
|
{DOMAIN_BINARY_SENSOR: add_entities}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -79,7 +72,7 @@ async def async_setup_entry(
|
|||||||
class LcnRegulatorLockSensor(LcnEntity, BinarySensorEntity):
|
class LcnRegulatorLockSensor(LcnEntity, BinarySensorEntity):
|
||||||
"""Representation of a LCN binary sensor for regulator locks."""
|
"""Representation of a LCN binary sensor for regulator locks."""
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN binary sensor."""
|
"""Initialize the LCN binary sensor."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -138,7 +131,7 @@ class LcnRegulatorLockSensor(LcnEntity, BinarySensorEntity):
|
|||||||
class LcnBinarySensor(LcnEntity, BinarySensorEntity):
|
class LcnBinarySensor(LcnEntity, BinarySensorEntity):
|
||||||
"""Representation of a LCN binary sensor for binary sensor ports."""
|
"""Representation of a LCN binary sensor for binary sensor ports."""
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN binary sensor."""
|
"""Initialize the LCN binary sensor."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -174,7 +167,7 @@ class LcnBinarySensor(LcnEntity, BinarySensorEntity):
|
|||||||
class LcnLockKeysSensor(LcnEntity, BinarySensorEntity):
|
class LcnLockKeysSensor(LcnEntity, BinarySensorEntity):
|
||||||
"""Representation of a LCN sensor for key locks."""
|
"""Representation of a LCN sensor for key locks."""
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN sensor."""
|
"""Initialize the LCN sensor."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ from homeassistant.components.climate import (
|
|||||||
ClimateEntityFeature,
|
ClimateEntityFeature,
|
||||||
HVACMode,
|
HVACMode,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_TEMPERATURE,
|
ATTR_TEMPERATURE,
|
||||||
CONF_DOMAIN,
|
CONF_DOMAIN,
|
||||||
@ -26,23 +25,21 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_DOMAIN_DATA,
|
CONF_DOMAIN_DATA,
|
||||||
CONF_LOCKABLE,
|
CONF_LOCKABLE,
|
||||||
CONF_MAX_TEMP,
|
CONF_MAX_TEMP,
|
||||||
CONF_MIN_TEMP,
|
CONF_MIN_TEMP,
|
||||||
CONF_SETPOINT,
|
CONF_SETPOINT,
|
||||||
CONF_TARGET_VALUE_LOCKED,
|
CONF_TARGET_VALUE_LOCKED,
|
||||||
DOMAIN,
|
|
||||||
)
|
)
|
||||||
from .entity import LcnEntity
|
from .entity import LcnEntity
|
||||||
from .helpers import InputType
|
from .helpers import InputType, LcnConfigEntry
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
def add_lcn_entities(
|
def add_lcn_entities(
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
entity_configs: Iterable[ConfigType],
|
entity_configs: Iterable[ConfigType],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -56,7 +53,7 @@ def add_lcn_entities(
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up LCN switch entities from a config entry."""
|
"""Set up LCN switch entities from a config entry."""
|
||||||
@ -66,7 +63,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities,
|
async_add_entities,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
|
config_entry.runtime_data.add_entities_callbacks.update(
|
||||||
{DOMAIN_CLIMATE: add_entities}
|
{DOMAIN_CLIMATE: add_entities}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,7 +79,7 @@ async def async_setup_entry(
|
|||||||
class LcnClimate(LcnEntity, ClimateEntity):
|
class LcnClimate(LcnEntity, ClimateEntity):
|
||||||
"""Representation of a LCN climate device."""
|
"""Representation of a LCN climate device."""
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize of a LCN climate device."""
|
"""Initialize of a LCN climate device."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
|
@ -15,12 +15,8 @@ PLATFORMS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
DOMAIN = "lcn"
|
DOMAIN = "lcn"
|
||||||
DATA_LCN = "lcn"
|
|
||||||
DEFAULT_NAME = "pchk"
|
DEFAULT_NAME = "pchk"
|
||||||
|
|
||||||
ADD_ENTITIES_CALLBACKS = "add_entities_callbacks"
|
|
||||||
CONNECTION = "connection"
|
|
||||||
DEVICE_CONNECTIONS = "device_connections"
|
|
||||||
CONF_HARDWARE_SERIAL = "hardware_serial"
|
CONF_HARDWARE_SERIAL = "hardware_serial"
|
||||||
CONF_SOFTWARE_SERIAL = "software_serial"
|
CONF_SOFTWARE_SERIAL = "software_serial"
|
||||||
CONF_HARDWARE_TYPE = "hardware_type"
|
CONF_HARDWARE_TYPE = "hardware_type"
|
||||||
|
@ -12,28 +12,25 @@ from homeassistant.components.cover import (
|
|||||||
CoverEntity,
|
CoverEntity,
|
||||||
CoverEntityFeature,
|
CoverEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES
|
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_DOMAIN_DATA,
|
CONF_DOMAIN_DATA,
|
||||||
CONF_MOTOR,
|
CONF_MOTOR,
|
||||||
CONF_POSITIONING_MODE,
|
CONF_POSITIONING_MODE,
|
||||||
CONF_REVERSE_TIME,
|
CONF_REVERSE_TIME,
|
||||||
DOMAIN,
|
|
||||||
)
|
)
|
||||||
from .entity import LcnEntity
|
from .entity import LcnEntity
|
||||||
from .helpers import InputType
|
from .helpers import InputType, LcnConfigEntry
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
def add_lcn_entities(
|
def add_lcn_entities(
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
entity_configs: Iterable[ConfigType],
|
entity_configs: Iterable[ConfigType],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -50,7 +47,7 @@ def add_lcn_entities(
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up LCN cover entities from a config entry."""
|
"""Set up LCN cover entities from a config entry."""
|
||||||
@ -60,7 +57,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities,
|
async_add_entities,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
|
config_entry.runtime_data.add_entities_callbacks.update(
|
||||||
{DOMAIN_COVER: add_entities}
|
{DOMAIN_COVER: add_entities}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ class LcnOutputsCover(LcnEntity, CoverEntity):
|
|||||||
_attr_is_opening = False
|
_attr_is_opening = False
|
||||||
_attr_assumed_state = True
|
_attr_assumed_state = True
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN cover."""
|
"""Initialize the LCN cover."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -188,7 +185,7 @@ class LcnRelayCover(LcnEntity, CoverEntity):
|
|||||||
|
|
||||||
positioning_mode: pypck.lcn_defs.MotorPositioningMode
|
positioning_mode: pypck.lcn_defs.MotorPositioningMode
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN cover."""
|
"""Initialize the LCN cover."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_ADDRESS, CONF_DOMAIN, CONF_NAME
|
from homeassistant.const import CONF_ADDRESS, CONF_DOMAIN, CONF_NAME
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
@ -13,6 +12,7 @@ from .helpers import (
|
|||||||
AddressType,
|
AddressType,
|
||||||
DeviceConnectionType,
|
DeviceConnectionType,
|
||||||
InputType,
|
InputType,
|
||||||
|
LcnConfigEntry,
|
||||||
generate_unique_id,
|
generate_unique_id,
|
||||||
get_device_connection,
|
get_device_connection,
|
||||||
get_resource,
|
get_resource,
|
||||||
@ -29,7 +29,7 @@ class LcnEntity(Entity):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the LCN device."""
|
"""Initialize the LCN device."""
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from collections.abc import Callable, Iterable
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from dataclasses import dataclass
|
||||||
import re
|
import re
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
import pypck
|
import pypck
|
||||||
|
from pypck.connection import PchkConnectionManager
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -33,12 +36,27 @@ from .const import (
|
|||||||
CONF_HARDWARE_TYPE,
|
CONF_HARDWARE_TYPE,
|
||||||
CONF_SCENES,
|
CONF_SCENES,
|
||||||
CONF_SOFTWARE_SERIAL,
|
CONF_SOFTWARE_SERIAL,
|
||||||
CONNECTION,
|
|
||||||
DEVICE_CONNECTIONS,
|
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LcnRuntimeData:
|
||||||
|
"""Data for LCN config entry."""
|
||||||
|
|
||||||
|
connection: PchkConnectionManager
|
||||||
|
"""Connection to PCHK host."""
|
||||||
|
|
||||||
|
device_connections: dict[str, DeviceConnectionType]
|
||||||
|
"""Logical addresses of devices connected to the host."""
|
||||||
|
|
||||||
|
add_entities_callbacks: dict[str, Callable[[Iterable[ConfigType]], None]]
|
||||||
|
"""Callbacks to add entities for platforms."""
|
||||||
|
|
||||||
|
|
||||||
# typing
|
# typing
|
||||||
|
type LcnConfigEntry = ConfigEntry[LcnRuntimeData]
|
||||||
|
|
||||||
type AddressType = tuple[int, int, bool]
|
type AddressType = tuple[int, int, bool]
|
||||||
type DeviceConnectionType = pypck.module.ModuleConnection | pypck.module.GroupConnection
|
type DeviceConnectionType = pypck.module.ModuleConnection | pypck.module.GroupConnection
|
||||||
|
|
||||||
@ -62,10 +80,10 @@ DOMAIN_LOOKUP = {
|
|||||||
|
|
||||||
|
|
||||||
def get_device_connection(
|
def get_device_connection(
|
||||||
hass: HomeAssistant, address: AddressType, config_entry: ConfigEntry
|
hass: HomeAssistant, address: AddressType, config_entry: LcnConfigEntry
|
||||||
) -> DeviceConnectionType:
|
) -> DeviceConnectionType:
|
||||||
"""Return a lcn device_connection."""
|
"""Return a lcn device_connection."""
|
||||||
host_connection = hass.data[DOMAIN][config_entry.entry_id][CONNECTION]
|
host_connection = config_entry.runtime_data.connection
|
||||||
addr = pypck.lcn_addr.LcnAddr(*address)
|
addr = pypck.lcn_addr.LcnAddr(*address)
|
||||||
return host_connection.get_address_conn(addr)
|
return host_connection.get_address_conn(addr)
|
||||||
|
|
||||||
@ -165,7 +183,7 @@ def purge_device_registry(
|
|||||||
device_registry.async_remove_device(device_id)
|
device_registry.async_remove_device(device_id)
|
||||||
|
|
||||||
|
|
||||||
def register_lcn_host_device(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
def register_lcn_host_device(hass: HomeAssistant, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Register LCN host for given config_entry in device registry."""
|
"""Register LCN host for given config_entry in device registry."""
|
||||||
device_registry = dr.async_get(hass)
|
device_registry = dr.async_get(hass)
|
||||||
|
|
||||||
@ -179,7 +197,7 @@ def register_lcn_host_device(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
|||||||
|
|
||||||
|
|
||||||
def register_lcn_address_devices(
|
def register_lcn_address_devices(
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry
|
hass: HomeAssistant, config_entry: LcnConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register LCN modules and groups defined in config_entry as devices in device registry.
|
"""Register LCN modules and groups defined in config_entry as devices in device registry.
|
||||||
|
|
||||||
@ -217,9 +235,9 @@ def register_lcn_address_devices(
|
|||||||
model=device_model,
|
model=device_model,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][DEVICE_CONNECTIONS][
|
config_entry.runtime_data.device_connections[device_entry.id] = (
|
||||||
device_entry.id
|
get_device_connection(hass, address, config_entry)
|
||||||
] = get_device_connection(hass, address, config_entry)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_update_device_config(
|
async def async_update_device_config(
|
||||||
@ -254,7 +272,7 @@ async def async_update_device_config(
|
|||||||
|
|
||||||
|
|
||||||
async def async_update_config_entry(
|
async def async_update_config_entry(
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry
|
hass: HomeAssistant, config_entry: LcnConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Fill missing values in config_entry with infos from LCN bus."""
|
"""Fill missing values in config_entry with infos from LCN bus."""
|
||||||
device_configs = deepcopy(config_entry.data[CONF_DEVICES])
|
device_configs = deepcopy(config_entry.data[CONF_DEVICES])
|
||||||
|
@ -14,29 +14,26 @@ from homeassistant.components.light import (
|
|||||||
LightEntity,
|
LightEntity,
|
||||||
LightEntityFeature,
|
LightEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES
|
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_DIMMABLE,
|
CONF_DIMMABLE,
|
||||||
CONF_DOMAIN_DATA,
|
CONF_DOMAIN_DATA,
|
||||||
CONF_OUTPUT,
|
CONF_OUTPUT,
|
||||||
CONF_TRANSITION,
|
CONF_TRANSITION,
|
||||||
DOMAIN,
|
|
||||||
OUTPUT_PORTS,
|
OUTPUT_PORTS,
|
||||||
)
|
)
|
||||||
from .entity import LcnEntity
|
from .entity import LcnEntity
|
||||||
from .helpers import InputType
|
from .helpers import InputType, LcnConfigEntry
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
def add_lcn_entities(
|
def add_lcn_entities(
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
entity_configs: Iterable[ConfigType],
|
entity_configs: Iterable[ConfigType],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -53,7 +50,7 @@ def add_lcn_entities(
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up LCN light entities from a config entry."""
|
"""Set up LCN light entities from a config entry."""
|
||||||
@ -63,7 +60,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities,
|
async_add_entities,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
|
config_entry.runtime_data.add_entities_callbacks.update(
|
||||||
{DOMAIN_LIGHT: add_entities}
|
{DOMAIN_LIGHT: add_entities}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -83,7 +80,7 @@ class LcnOutputLight(LcnEntity, LightEntity):
|
|||||||
_attr_is_on = False
|
_attr_is_on = False
|
||||||
_attr_brightness = 255
|
_attr_brightness = 255
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN light."""
|
"""Initialize the LCN light."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -175,7 +172,7 @@ class LcnRelayLight(LcnEntity, LightEntity):
|
|||||||
_attr_supported_color_modes = {ColorMode.ONOFF}
|
_attr_supported_color_modes = {ColorMode.ONOFF}
|
||||||
_attr_is_on = False
|
_attr_is_on = False
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN light."""
|
"""Initialize the LCN light."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
|
@ -7,28 +7,26 @@ from typing import Any
|
|||||||
import pypck
|
import pypck
|
||||||
|
|
||||||
from homeassistant.components.scene import DOMAIN as DOMAIN_SCENE, Scene
|
from homeassistant.components.scene import DOMAIN as DOMAIN_SCENE, Scene
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES, CONF_SCENE
|
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES, CONF_SCENE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_DOMAIN_DATA,
|
CONF_DOMAIN_DATA,
|
||||||
CONF_OUTPUTS,
|
CONF_OUTPUTS,
|
||||||
CONF_REGISTER,
|
CONF_REGISTER,
|
||||||
CONF_TRANSITION,
|
CONF_TRANSITION,
|
||||||
DOMAIN,
|
|
||||||
OUTPUT_PORTS,
|
OUTPUT_PORTS,
|
||||||
)
|
)
|
||||||
from .entity import LcnEntity
|
from .entity import LcnEntity
|
||||||
|
from .helpers import LcnConfigEntry
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
def add_lcn_entities(
|
def add_lcn_entities(
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
entity_configs: Iterable[ConfigType],
|
entity_configs: Iterable[ConfigType],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -42,7 +40,7 @@ def add_lcn_entities(
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up LCN switch entities from a config entry."""
|
"""Set up LCN switch entities from a config entry."""
|
||||||
@ -52,7 +50,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities,
|
async_add_entities,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
|
config_entry.runtime_data.add_entities_callbacks.update(
|
||||||
{DOMAIN_SCENE: add_entities}
|
{DOMAIN_SCENE: add_entities}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -68,7 +66,7 @@ async def async_setup_entry(
|
|||||||
class LcnScene(LcnEntity, Scene):
|
class LcnScene(LcnEntity, Scene):
|
||||||
"""Representation of a LCN scene."""
|
"""Representation of a LCN scene."""
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN scene."""
|
"""Initialize the LCN scene."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ from homeassistant.components.sensor import (
|
|||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
SensorEntity,
|
SensorEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
CONF_DOMAIN,
|
CONF_DOMAIN,
|
||||||
@ -29,9 +28,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_DOMAIN_DATA,
|
CONF_DOMAIN_DATA,
|
||||||
DOMAIN,
|
|
||||||
LED_PORTS,
|
LED_PORTS,
|
||||||
S0_INPUTS,
|
S0_INPUTS,
|
||||||
SETPOINTS,
|
SETPOINTS,
|
||||||
@ -39,7 +36,7 @@ from .const import (
|
|||||||
VARIABLES,
|
VARIABLES,
|
||||||
)
|
)
|
||||||
from .entity import LcnEntity
|
from .entity import LcnEntity
|
||||||
from .helpers import InputType
|
from .helpers import InputType, LcnConfigEntry
|
||||||
|
|
||||||
DEVICE_CLASS_MAPPING = {
|
DEVICE_CLASS_MAPPING = {
|
||||||
pypck.lcn_defs.VarUnit.CELSIUS: SensorDeviceClass.TEMPERATURE,
|
pypck.lcn_defs.VarUnit.CELSIUS: SensorDeviceClass.TEMPERATURE,
|
||||||
@ -67,7 +64,7 @@ UNIT_OF_MEASUREMENT_MAPPING = {
|
|||||||
|
|
||||||
|
|
||||||
def add_lcn_entities(
|
def add_lcn_entities(
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
entity_configs: Iterable[ConfigType],
|
entity_configs: Iterable[ConfigType],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -86,7 +83,7 @@ def add_lcn_entities(
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up LCN switch entities from a config entry."""
|
"""Set up LCN switch entities from a config entry."""
|
||||||
@ -96,7 +93,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities,
|
async_add_entities,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
|
config_entry.runtime_data.add_entities_callbacks.update(
|
||||||
{DOMAIN_SENSOR: add_entities}
|
{DOMAIN_SENSOR: add_entities}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -112,7 +109,7 @@ async def async_setup_entry(
|
|||||||
class LcnVariableSensor(LcnEntity, SensorEntity):
|
class LcnVariableSensor(LcnEntity, SensorEntity):
|
||||||
"""Representation of a LCN sensor for variables."""
|
"""Representation of a LCN sensor for variables."""
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN sensor."""
|
"""Initialize the LCN sensor."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -157,7 +154,7 @@ class LcnVariableSensor(LcnEntity, SensorEntity):
|
|||||||
class LcnLedLogicSensor(LcnEntity, SensorEntity):
|
class LcnLedLogicSensor(LcnEntity, SensorEntity):
|
||||||
"""Representation of a LCN sensor for leds and logicops."""
|
"""Representation of a LCN sensor for leds and logicops."""
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN sensor."""
|
"""Initialize the LCN sensor."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ from .const import (
|
|||||||
CONF_TRANSITION,
|
CONF_TRANSITION,
|
||||||
CONF_VALUE,
|
CONF_VALUE,
|
||||||
CONF_VARIABLE,
|
CONF_VARIABLE,
|
||||||
DEVICE_CONNECTIONS,
|
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
LED_PORTS,
|
LED_PORTS,
|
||||||
LED_STATUS,
|
LED_STATUS,
|
||||||
@ -49,7 +48,7 @@ from .const import (
|
|||||||
VAR_UNITS,
|
VAR_UNITS,
|
||||||
VARIABLES,
|
VARIABLES,
|
||||||
)
|
)
|
||||||
from .helpers import DeviceConnectionType, is_states_string
|
from .helpers import DeviceConnectionType, LcnConfigEntry, is_states_string
|
||||||
|
|
||||||
|
|
||||||
class LcnServiceCall:
|
class LcnServiceCall:
|
||||||
@ -68,18 +67,28 @@ class LcnServiceCall:
|
|||||||
|
|
||||||
def get_device_connection(self, service: ServiceCall) -> DeviceConnectionType:
|
def get_device_connection(self, service: ServiceCall) -> DeviceConnectionType:
|
||||||
"""Get address connection object."""
|
"""Get address connection object."""
|
||||||
|
entries: list[LcnConfigEntry] = self.hass.config_entries.async_loaded_entries(
|
||||||
|
DOMAIN
|
||||||
|
)
|
||||||
device_id = service.data[CONF_DEVICE_ID]
|
device_id = service.data[CONF_DEVICE_ID]
|
||||||
device_registry = dr.async_get(self.hass)
|
device_registry = dr.async_get(self.hass)
|
||||||
if not (device := device_registry.async_get(device_id)):
|
if not (device := device_registry.async_get(device_id)) or not (
|
||||||
|
entry := next(
|
||||||
|
(
|
||||||
|
entry
|
||||||
|
for entry in entries
|
||||||
|
if entry.entry_id == device.primary_config_entry
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
):
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_device_id",
|
translation_key="invalid_device_id",
|
||||||
translation_placeholders={"device_id": device_id},
|
translation_placeholders={"device_id": device_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.hass.data[DOMAIN][device.primary_config_entry][DEVICE_CONNECTIONS][
|
return entry.runtime_data.device_connections[device_id]
|
||||||
device_id
|
|
||||||
]
|
|
||||||
|
|
||||||
async def async_call_service(self, service: ServiceCall) -> ServiceResponse:
|
async def async_call_service(self, service: ServiceCall) -> ServiceResponse:
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
|
@ -7,29 +7,20 @@ from typing import Any
|
|||||||
import pypck
|
import pypck
|
||||||
|
|
||||||
from homeassistant.components.switch import DOMAIN as DOMAIN_SWITCH, SwitchEntity
|
from homeassistant.components.switch import DOMAIN as DOMAIN_SWITCH, SwitchEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES
|
from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import (
|
from .const import CONF_DOMAIN_DATA, CONF_OUTPUT, OUTPUT_PORTS, RELAY_PORTS, SETPOINTS
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_DOMAIN_DATA,
|
|
||||||
CONF_OUTPUT,
|
|
||||||
DOMAIN,
|
|
||||||
OUTPUT_PORTS,
|
|
||||||
RELAY_PORTS,
|
|
||||||
SETPOINTS,
|
|
||||||
)
|
|
||||||
from .entity import LcnEntity
|
from .entity import LcnEntity
|
||||||
from .helpers import InputType
|
from .helpers import InputType, LcnConfigEntry
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
def add_lcn_switch_entities(
|
def add_lcn_switch_entities(
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
entity_configs: Iterable[ConfigType],
|
entity_configs: Iterable[ConfigType],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -52,7 +43,7 @@ def add_lcn_switch_entities(
|
|||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up LCN switch entities from a config entry."""
|
"""Set up LCN switch entities from a config entry."""
|
||||||
@ -62,7 +53,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities,
|
async_add_entities,
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
|
config_entry.runtime_data.add_entities_callbacks.update(
|
||||||
{DOMAIN_SWITCH: add_entities}
|
{DOMAIN_SWITCH: add_entities}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -80,7 +71,7 @@ class LcnOutputSwitch(LcnEntity, SwitchEntity):
|
|||||||
|
|
||||||
_attr_is_on = False
|
_attr_is_on = False
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN switch."""
|
"""Initialize the LCN switch."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -129,7 +120,7 @@ class LcnRelaySwitch(LcnEntity, SwitchEntity):
|
|||||||
|
|
||||||
_attr_is_on = False
|
_attr_is_on = False
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN switch."""
|
"""Initialize the LCN switch."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -179,7 +170,7 @@ class LcnRegulatorLockSwitch(LcnEntity, SwitchEntity):
|
|||||||
|
|
||||||
_attr_is_on = False
|
_attr_is_on = False
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN switch."""
|
"""Initialize the LCN switch."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
@ -235,7 +226,7 @@ class LcnKeyLockSwitch(LcnEntity, SwitchEntity):
|
|||||||
|
|
||||||
_attr_is_on = False
|
_attr_is_on = False
|
||||||
|
|
||||||
def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
|
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
|
||||||
"""Initialize the LCN switch."""
|
"""Initialize the LCN switch."""
|
||||||
super().__init__(config, config_entry)
|
super().__init__(config, config_entry)
|
||||||
|
|
||||||
|
@ -4,15 +4,17 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from collections.abc import Awaitable, Callable
|
from collections.abc import Awaitable, Callable
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import TYPE_CHECKING, Any, Final
|
from typing import Any, Final
|
||||||
|
|
||||||
import lcn_frontend as lcn_panel
|
import lcn_frontend as lcn_panel
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components import panel_custom, websocket_api
|
from homeassistant.components import panel_custom, websocket_api
|
||||||
from homeassistant.components.http import StaticPathConfig
|
from homeassistant.components.http import StaticPathConfig
|
||||||
from homeassistant.components.websocket_api import AsyncWebSocketCommandHandler
|
from homeassistant.components.websocket_api import (
|
||||||
from homeassistant.config_entries import ConfigEntry
|
ActiveConnection,
|
||||||
|
AsyncWebSocketCommandHandler,
|
||||||
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_ADDRESS,
|
CONF_ADDRESS,
|
||||||
CONF_DEVICES,
|
CONF_DEVICES,
|
||||||
@ -28,16 +30,15 @@ from homeassistant.helpers import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_ENTITIES_CALLBACKS,
|
|
||||||
CONF_DOMAIN_DATA,
|
CONF_DOMAIN_DATA,
|
||||||
CONF_HARDWARE_SERIAL,
|
CONF_HARDWARE_SERIAL,
|
||||||
CONF_HARDWARE_TYPE,
|
CONF_HARDWARE_TYPE,
|
||||||
CONF_SOFTWARE_SERIAL,
|
CONF_SOFTWARE_SERIAL,
|
||||||
CONNECTION,
|
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
from .helpers import (
|
from .helpers import (
|
||||||
DeviceConnectionType,
|
DeviceConnectionType,
|
||||||
|
LcnConfigEntry,
|
||||||
async_update_device_config,
|
async_update_device_config,
|
||||||
generate_unique_id,
|
generate_unique_id,
|
||||||
get_device_config,
|
get_device_config,
|
||||||
@ -58,11 +59,8 @@ from .schemas import (
|
|||||||
DOMAIN_DATA_SWITCH,
|
DOMAIN_DATA_SWITCH,
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.websocket_api import ActiveConnection
|
|
||||||
|
|
||||||
type AsyncLcnWebSocketCommandHandler = Callable[
|
type AsyncLcnWebSocketCommandHandler = Callable[
|
||||||
[HomeAssistant, ActiveConnection, dict[str, Any], ConfigEntry], Awaitable[None]
|
[HomeAssistant, ActiveConnection, dict[str, Any], LcnConfigEntry], Awaitable[None]
|
||||||
]
|
]
|
||||||
|
|
||||||
URL_BASE: Final = "/lcn_static"
|
URL_BASE: Final = "/lcn_static"
|
||||||
@ -127,7 +125,7 @@ async def websocket_get_device_configs(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
connection: websocket_api.ActiveConnection,
|
connection: websocket_api.ActiveConnection,
|
||||||
msg: dict,
|
msg: dict,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Get device configs."""
|
"""Get device configs."""
|
||||||
connection.send_result(msg["id"], config_entry.data[CONF_DEVICES])
|
connection.send_result(msg["id"], config_entry.data[CONF_DEVICES])
|
||||||
@ -147,7 +145,7 @@ async def websocket_get_entity_configs(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
connection: websocket_api.ActiveConnection,
|
connection: websocket_api.ActiveConnection,
|
||||||
msg: dict,
|
msg: dict,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Get entities configs."""
|
"""Get entities configs."""
|
||||||
if CONF_ADDRESS in msg:
|
if CONF_ADDRESS in msg:
|
||||||
@ -178,10 +176,10 @@ async def websocket_scan_devices(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
connection: websocket_api.ActiveConnection,
|
connection: websocket_api.ActiveConnection,
|
||||||
msg: dict,
|
msg: dict,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Scan for new devices."""
|
"""Scan for new devices."""
|
||||||
host_connection = hass.data[DOMAIN][config_entry.entry_id][CONNECTION]
|
host_connection = config_entry.runtime_data.connection
|
||||||
await host_connection.scan_modules()
|
await host_connection.scan_modules()
|
||||||
|
|
||||||
for device_connection in host_connection.address_conns.values():
|
for device_connection in host_connection.address_conns.values():
|
||||||
@ -210,7 +208,7 @@ async def websocket_add_device(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
connection: websocket_api.ActiveConnection,
|
connection: websocket_api.ActiveConnection,
|
||||||
msg: dict,
|
msg: dict,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add a device."""
|
"""Add a device."""
|
||||||
if get_device_config(msg[CONF_ADDRESS], config_entry):
|
if get_device_config(msg[CONF_ADDRESS], config_entry):
|
||||||
@ -256,7 +254,7 @@ async def websocket_delete_device(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
connection: websocket_api.ActiveConnection,
|
connection: websocket_api.ActiveConnection,
|
||||||
msg: dict,
|
msg: dict,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Delete a device."""
|
"""Delete a device."""
|
||||||
device_config = get_device_config(msg[CONF_ADDRESS], config_entry)
|
device_config = get_device_config(msg[CONF_ADDRESS], config_entry)
|
||||||
@ -318,7 +316,7 @@ async def websocket_add_entity(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
connection: websocket_api.ActiveConnection,
|
connection: websocket_api.ActiveConnection,
|
||||||
msg: dict,
|
msg: dict,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add an entity."""
|
"""Add an entity."""
|
||||||
if not (device_config := get_device_config(msg[CONF_ADDRESS], config_entry)):
|
if not (device_config := get_device_config(msg[CONF_ADDRESS], config_entry)):
|
||||||
@ -347,9 +345,7 @@ async def websocket_add_entity(
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Create new entity and add to corresponding component
|
# Create new entity and add to corresponding component
|
||||||
add_entities = hass.data[DOMAIN][msg["entry_id"]][ADD_ENTITIES_CALLBACKS][
|
add_entities = config_entry.runtime_data.add_entities_callbacks[msg[CONF_DOMAIN]]
|
||||||
msg[CONF_DOMAIN]
|
|
||||||
]
|
|
||||||
add_entities([entity_config])
|
add_entities([entity_config])
|
||||||
|
|
||||||
# Add entity config to config_entry
|
# Add entity config to config_entry
|
||||||
@ -386,7 +382,7 @@ async def websocket_delete_entity(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
connection: websocket_api.ActiveConnection,
|
connection: websocket_api.ActiveConnection,
|
||||||
msg: dict,
|
msg: dict,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Delete an entity."""
|
"""Delete an entity."""
|
||||||
entity_config = next(
|
entity_config = next(
|
||||||
@ -426,7 +422,7 @@ async def websocket_delete_entity(
|
|||||||
async def async_create_or_update_device_in_config_entry(
|
async def async_create_or_update_device_in_config_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
device_connection: DeviceConnectionType,
|
device_connection: DeviceConnectionType,
|
||||||
config_entry: ConfigEntry,
|
config_entry: LcnConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create or update device in config_entry according to given device_connection."""
|
"""Create or update device in config_entry according to given device_connection."""
|
||||||
address = (
|
address = (
|
||||||
@ -455,7 +451,7 @@ async def async_create_or_update_device_in_config_entry(
|
|||||||
|
|
||||||
|
|
||||||
def get_entity_entry(
|
def get_entity_entry(
|
||||||
hass: HomeAssistant, entity_config: dict, config_entry: ConfigEntry
|
hass: HomeAssistant, entity_config: dict, config_entry: LcnConfigEntry
|
||||||
) -> er.RegistryEntry | None:
|
) -> er.RegistryEntry | None:
|
||||||
"""Get entity RegistryEntry from entity_config."""
|
"""Get entity RegistryEntry from entity_config."""
|
||||||
entity_registry = er.async_get(hass)
|
entity_registry = er.async_get(hass)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user