Fix Duco box device removal on partial node refreshes (#173186)
This commit is contained in:
committed by
GitHub
parent
c3d6ad029f
commit
f58e0e5234
@@ -7,3 +7,4 @@ from homeassistant.const import Platform
|
||||
DOMAIN = "duco"
|
||||
PLATFORMS = [Platform.FAN, Platform.SENSOR]
|
||||
SCAN_INTERVAL = timedelta(seconds=10)
|
||||
BOX_NODE_ID = 1
|
||||
|
||||
@@ -24,7 +24,7 @@ from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import BOX_NODE_ID, DOMAIN
|
||||
from .coordinator import DucoConfigEntry, DucoCoordinator
|
||||
from .entity import DucoEntity
|
||||
|
||||
@@ -158,7 +158,13 @@ async def async_setup_entry(
|
||||
# The firmware removes deregistered RF/wired nodes automatically.
|
||||
# BSRH box sensors that are physically unplugged from the PCB are
|
||||
# not deregistered by the firmware and will never appear here as stale.
|
||||
stale_node_ids = known_nodes - coordinator.data.nodes.keys()
|
||||
# The BOX node can transiently disappear from the API response, so keep
|
||||
# node 1 to avoid removing the main controller device.
|
||||
stale_node_ids = {
|
||||
node_id
|
||||
for node_id in known_nodes - coordinator.data.nodes.keys()
|
||||
if node_id != BOX_NODE_ID
|
||||
}
|
||||
if stale_node_ids:
|
||||
device_reg = dr.async_get(hass)
|
||||
mac = entry.unique_id
|
||||
|
||||
@@ -17,7 +17,7 @@ from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.duco.const import DOMAIN, SCAN_INTERVAL
|
||||
from homeassistant.components.duco.const import BOX_NODE_ID, DOMAIN, SCAN_INTERVAL
|
||||
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
@@ -212,6 +212,56 @@ async def test_deregistered_node_removes_device(
|
||||
assert device is None
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_box_node_not_removed_on_transient_incomplete_node_list(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_duco_client: AsyncMock,
|
||||
mock_sensor_nodes: list[Node],
|
||||
freezer: FrozenDateTimeFactory,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test BOX-linked entities survive a transient node list without node 1."""
|
||||
await setup_platform_integration(
|
||||
hass, mock_config_entry, [Platform.FAN, Platform.SENSOR]
|
||||
)
|
||||
|
||||
box_device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_{BOX_NODE_ID}")}
|
||||
)
|
||||
assert box_device is not None
|
||||
assert hass.states.get("fan.living") is not None
|
||||
|
||||
mock_duco_client.async_get_nodes.return_value = [
|
||||
node for node in mock_sensor_nodes if node.node_id != BOX_NODE_ID
|
||||
]
|
||||
|
||||
freezer.tick(SCAN_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert (
|
||||
device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_{BOX_NODE_ID}")}
|
||||
)
|
||||
is not None
|
||||
)
|
||||
state = hass.states.get("fan.living")
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
mock_duco_client.async_get_nodes.return_value = mock_sensor_nodes
|
||||
|
||||
freezer.tick(SCAN_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
state = hass.states.get("fan.living")
|
||||
assert state is not None
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_unknown_node_type_logs_warning_and_creates_no_entities(
|
||||
hass: HomeAssistant,
|
||||
|
||||
Reference in New Issue
Block a user