mirror of
https://github.com/home-assistant/core.git
synced 2025-07-29 18:28:14 +02:00
Consolidate device info and clean-up ISY994 code base (#85657)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
@ -21,6 +21,7 @@ from homeassistant.components.binary_sensor import (
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import STATE_ON, Platform
|
||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.event import async_track_point_in_utc_time
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
@ -30,9 +31,10 @@ from .const import (
|
||||
_LOGGER,
|
||||
BINARY_SENSOR_DEVICE_TYPES_ISY,
|
||||
BINARY_SENSOR_DEVICE_TYPES_ZWAVE,
|
||||
DOMAIN as ISY994_DOMAIN,
|
||||
ISY994_NODES,
|
||||
ISY994_PROGRAMS,
|
||||
DOMAIN,
|
||||
ISY_DEVICES,
|
||||
ISY_NODES,
|
||||
ISY_PROGRAMS,
|
||||
SUBNODE_CLIMATE_COOL,
|
||||
SUBNODE_CLIMATE_HEAT,
|
||||
SUBNODE_DUSK_DAWN,
|
||||
@ -70,27 +72,33 @@ async def async_setup_entry(
|
||||
| ISYBinarySensorHeartbeat
|
||||
| ISYBinarySensorProgramEntity,
|
||||
] = {}
|
||||
child_nodes: list[tuple[Node, BinarySensorDeviceClass | None, str | None]] = []
|
||||
child_nodes: list[
|
||||
tuple[Node, BinarySensorDeviceClass | None, str | None, DeviceInfo | None]
|
||||
] = []
|
||||
entity: ISYInsteonBinarySensorEntity | ISYBinarySensorEntity | ISYBinarySensorHeartbeat | ISYBinarySensorProgramEntity
|
||||
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
for node in hass_isy_data[ISY994_NODES][Platform.BINARY_SENSOR]:
|
||||
hass_isy_data = hass.data[DOMAIN][entry.entry_id]
|
||||
devices: dict[str, DeviceInfo] = hass_isy_data[ISY_DEVICES]
|
||||
for node in hass_isy_data[ISY_NODES][Platform.BINARY_SENSOR]:
|
||||
assert isinstance(node, Node)
|
||||
device_info = devices.get(node.primary_node)
|
||||
device_class, device_type = _detect_device_type_and_class(node)
|
||||
if node.protocol == PROTO_INSTEON:
|
||||
if node.parent_node is not None:
|
||||
# We'll process the Insteon child nodes last, to ensure all parent
|
||||
# nodes have been processed
|
||||
child_nodes.append((node, device_class, device_type))
|
||||
child_nodes.append((node, device_class, device_type, device_info))
|
||||
continue
|
||||
entity = ISYInsteonBinarySensorEntity(node, device_class)
|
||||
entity = ISYInsteonBinarySensorEntity(
|
||||
node, device_class, device_info=device_info
|
||||
)
|
||||
else:
|
||||
entity = ISYBinarySensorEntity(node, device_class)
|
||||
entity = ISYBinarySensorEntity(node, device_class, device_info=device_info)
|
||||
entities.append(entity)
|
||||
entities_by_address[node.address] = entity
|
||||
|
||||
# Handle some special child node cases for Insteon Devices
|
||||
for (node, device_class, device_type) in child_nodes:
|
||||
for (node, device_class, device_type, device_info) in child_nodes:
|
||||
subnode_id = int(node.address.split(" ")[-1], 16)
|
||||
# Handle Insteon Thermostats
|
||||
if device_type is not None and device_type.startswith(TYPE_CATEGORY_CLIMATE):
|
||||
@ -101,13 +109,13 @@ async def async_setup_entry(
|
||||
# As soon as the ISY Event Stream connects if it has a
|
||||
# valid state, it will be set.
|
||||
entity = ISYInsteonBinarySensorEntity(
|
||||
node, BinarySensorDeviceClass.COLD, False
|
||||
node, BinarySensorDeviceClass.COLD, False, device_info=device_info
|
||||
)
|
||||
entities.append(entity)
|
||||
elif subnode_id == SUBNODE_CLIMATE_HEAT:
|
||||
# Subnode 3 is the "Heat Control" sensor
|
||||
entity = ISYInsteonBinarySensorEntity(
|
||||
node, BinarySensorDeviceClass.HEAT, False
|
||||
node, BinarySensorDeviceClass.HEAT, False, device_info=device_info
|
||||
)
|
||||
entities.append(entity)
|
||||
continue
|
||||
@ -138,7 +146,9 @@ async def async_setup_entry(
|
||||
assert isinstance(parent_entity, ISYInsteonBinarySensorEntity)
|
||||
# Subnode 4 is the heartbeat node, which we will
|
||||
# represent as a separate binary_sensor
|
||||
entity = ISYBinarySensorHeartbeat(node, parent_entity)
|
||||
entity = ISYBinarySensorHeartbeat(
|
||||
node, parent_entity, device_info=device_info
|
||||
)
|
||||
parent_entity.add_heartbeat_device(entity)
|
||||
entities.append(entity)
|
||||
continue
|
||||
@ -157,14 +167,17 @@ async def async_setup_entry(
|
||||
if subnode_id == SUBNODE_DUSK_DAWN:
|
||||
# Subnode 2 is the Dusk/Dawn sensor
|
||||
entity = ISYInsteonBinarySensorEntity(
|
||||
node, BinarySensorDeviceClass.LIGHT
|
||||
node, BinarySensorDeviceClass.LIGHT, device_info=device_info
|
||||
)
|
||||
entities.append(entity)
|
||||
continue
|
||||
if subnode_id == SUBNODE_LOW_BATTERY:
|
||||
# Subnode 3 is the low battery node
|
||||
entity = ISYInsteonBinarySensorEntity(
|
||||
node, BinarySensorDeviceClass.BATTERY, initial_state
|
||||
node,
|
||||
BinarySensorDeviceClass.BATTERY,
|
||||
initial_state,
|
||||
device_info=device_info,
|
||||
)
|
||||
entities.append(entity)
|
||||
continue
|
||||
@ -172,22 +185,27 @@ async def async_setup_entry(
|
||||
# Tamper Sub-node for MS II. Sometimes reported as "A" sometimes
|
||||
# reported as "10", which translate from Hex to 10 and 16 resp.
|
||||
entity = ISYInsteonBinarySensorEntity(
|
||||
node, BinarySensorDeviceClass.PROBLEM, initial_state
|
||||
node,
|
||||
BinarySensorDeviceClass.PROBLEM,
|
||||
initial_state,
|
||||
device_info=device_info,
|
||||
)
|
||||
entities.append(entity)
|
||||
continue
|
||||
if subnode_id in SUBNODE_MOTION_DISABLED:
|
||||
# Motion Disabled Sub-node for MS II ("D" or "13")
|
||||
entity = ISYInsteonBinarySensorEntity(node)
|
||||
entity = ISYInsteonBinarySensorEntity(node, device_info=device_info)
|
||||
entities.append(entity)
|
||||
continue
|
||||
|
||||
# We don't yet have any special logic for other sensor
|
||||
# types, so add the nodes as individual devices
|
||||
entity = ISYBinarySensorEntity(node, device_class)
|
||||
entity = ISYBinarySensorEntity(
|
||||
node, force_device_class=device_class, device_info=device_info
|
||||
)
|
||||
entities.append(entity)
|
||||
|
||||
for name, status, _ in hass_isy_data[ISY994_PROGRAMS][Platform.BINARY_SENSOR]:
|
||||
for name, status, _ in hass_isy_data[ISY_PROGRAMS][Platform.BINARY_SENSOR]:
|
||||
entities.append(ISYBinarySensorProgramEntity(name, status))
|
||||
|
||||
async_add_entities(entities)
|
||||
@ -225,9 +243,10 @@ class ISYBinarySensorEntity(ISYNodeEntity, BinarySensorEntity):
|
||||
node: Node,
|
||||
force_device_class: BinarySensorDeviceClass | None = None,
|
||||
unknown_state: bool | None = None,
|
||||
device_info: DeviceInfo | None = None,
|
||||
) -> None:
|
||||
"""Initialize the ISY binary sensor device."""
|
||||
super().__init__(node)
|
||||
super().__init__(node, device_info=device_info)
|
||||
self._device_class = force_device_class
|
||||
|
||||
@property
|
||||
@ -260,9 +279,10 @@ class ISYInsteonBinarySensorEntity(ISYBinarySensorEntity):
|
||||
node: Node,
|
||||
force_device_class: BinarySensorDeviceClass | None = None,
|
||||
unknown_state: bool | None = None,
|
||||
device_info: DeviceInfo | None = None,
|
||||
) -> None:
|
||||
"""Initialize the ISY binary sensor device."""
|
||||
super().__init__(node, force_device_class)
|
||||
super().__init__(node, force_device_class, device_info=device_info)
|
||||
self._negative_node: Node | None = None
|
||||
self._heartbeat_device: ISYBinarySensorHeartbeat | None = None
|
||||
if self._node.status == ISY_VALUE_UNKNOWN:
|
||||
@ -399,6 +419,7 @@ class ISYBinarySensorHeartbeat(ISYNodeEntity, BinarySensorEntity, RestoreEntity)
|
||||
| ISYBinarySensorEntity
|
||||
| ISYBinarySensorHeartbeat
|
||||
| ISYBinarySensorProgramEntity,
|
||||
device_info: DeviceInfo | None = None,
|
||||
) -> None:
|
||||
"""Initialize the ISY binary sensor device.
|
||||
|
||||
@ -409,7 +430,7 @@ class ISYBinarySensorHeartbeat(ISYNodeEntity, BinarySensorEntity, RestoreEntity)
|
||||
If the heartbeat is not received in 25 hours then the computed state is
|
||||
set to ON (Low Battery).
|
||||
"""
|
||||
super().__init__(node)
|
||||
super().__init__(node, device_info=device_info)
|
||||
self._parent_device = parent_device
|
||||
self._heartbeat_timer: CALLBACK_TYPE | None = None
|
||||
self._computed_state: bool | None = None
|
||||
|
Reference in New Issue
Block a user