Fix duplicate unique id issue in Sensibo (#139582)

* Fix duplicate unique id issue in Sensibo

* Fixes

* Mods
This commit is contained in:
G Johansson 2025-03-02 00:04:13 +01:00 committed by GitHub
parent 3e9304253d
commit e3eb6051de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 40 additions and 18 deletions

View File

@ -130,9 +130,10 @@ async def async_setup_entry(
"""Handle additions of devices and sensors.""" """Handle additions of devices and sensors."""
entities: list[SensiboMotionSensor | SensiboDeviceSensor] = [] entities: list[SensiboMotionSensor | SensiboDeviceSensor] = []
nonlocal added_devices nonlocal added_devices
new_devices, remove_devices, added_devices = coordinator.get_devices( new_devices, remove_devices, new_added_devices = coordinator.get_devices(
added_devices added_devices
) )
added_devices = new_added_devices
if LOGGER.isEnabledFor(logging.DEBUG): if LOGGER.isEnabledFor(logging.DEBUG):
LOGGER.debug( LOGGER.debug(
@ -168,7 +169,6 @@ async def async_setup_entry(
device_data.model, DEVICE_SENSOR_TYPES device_data.model, DEVICE_SENSOR_TYPES
) )
) )
async_add_entities(entities) async_add_entities(entities)
entry.async_on_unload(coordinator.async_add_listener(_add_remove_devices)) entry.async_on_unload(coordinator.async_add_listener(_add_remove_devices))

View File

@ -46,7 +46,8 @@ async def async_setup_entry(
def _add_remove_devices() -> None: def _add_remove_devices() -> None:
"""Handle additions of devices and sensors.""" """Handle additions of devices and sensors."""
nonlocal added_devices nonlocal added_devices
new_devices, _, added_devices = coordinator.get_devices(added_devices) new_devices, _, new_added_devices = coordinator.get_devices(added_devices)
added_devices = new_added_devices
if new_devices: if new_devices:
async_add_entities( async_add_entities(

View File

@ -149,7 +149,8 @@ async def async_setup_entry(
def _add_remove_devices() -> None: def _add_remove_devices() -> None:
"""Handle additions of devices and sensors.""" """Handle additions of devices and sensors."""
nonlocal added_devices nonlocal added_devices
new_devices, _, added_devices = coordinator.get_devices(added_devices) new_devices, _, new_added_devices = coordinator.get_devices(added_devices)
added_devices = new_added_devices
if new_devices: if new_devices:
async_add_entities( async_add_entities(

View File

@ -56,18 +56,31 @@ class SensiboDataUpdateCoordinator(DataUpdateCoordinator[SensiboData]):
) -> tuple[set[str], set[str], set[str]]: ) -> tuple[set[str], set[str], set[str]]:
"""Addition and removal of devices.""" """Addition and removal of devices."""
data = self.data data = self.data
motion_sensors = { current_motion_sensors = {
sensor_id sensor_id
for device_data in data.parsed.values() for device_data in data.parsed.values()
if device_data.motion_sensors if device_data.motion_sensors
for sensor_id in device_data.motion_sensors for sensor_id in device_data.motion_sensors
} }
devices: set[str] = set(data.parsed) current_devices: set[str] = set(data.parsed)
new_devices: set[str] = motion_sensors | devices - added_devices LOGGER.debug(
remove_devices = added_devices - devices - motion_sensors "Current devices: %s, moption sensors: %s",
added_devices = (added_devices - remove_devices) | new_devices current_devices,
current_motion_sensors,
)
new_devices: set[str] = (
current_motion_sensors | current_devices
) - added_devices
remove_devices = added_devices - current_devices - current_motion_sensors
new_added_devices = (added_devices - remove_devices) | new_devices
return (new_devices, remove_devices, added_devices) LOGGER.debug(
"New devices: %s, Removed devices: %s, Added devices: %s",
new_devices,
remove_devices,
new_added_devices,
)
return (new_devices, remove_devices, new_added_devices)
async def _async_update_data(self) -> SensiboData: async def _async_update_data(self) -> SensiboData:
"""Fetch data from Sensibo.""" """Fetch data from Sensibo."""

View File

@ -76,7 +76,8 @@ async def async_setup_entry(
def _add_remove_devices() -> None: def _add_remove_devices() -> None:
"""Handle additions of devices and sensors.""" """Handle additions of devices and sensors."""
nonlocal added_devices nonlocal added_devices
new_devices, _, added_devices = coordinator.get_devices(added_devices) new_devices, _, new_added_devices = coordinator.get_devices(added_devices)
added_devices = new_added_devices
if new_devices: if new_devices:
async_add_entities( async_add_entities(

View File

@ -115,7 +115,8 @@ async def async_setup_entry(
def _add_remove_devices() -> None: def _add_remove_devices() -> None:
"""Handle additions of devices and sensors.""" """Handle additions of devices and sensors."""
nonlocal added_devices nonlocal added_devices
new_devices, _, added_devices = coordinator.get_devices(added_devices) new_devices, _, new_added_devices = coordinator.get_devices(added_devices)
added_devices = new_added_devices
if new_devices: if new_devices:
async_add_entities( async_add_entities(

View File

@ -253,9 +253,8 @@ async def async_setup_entry(
entities: list[SensiboMotionSensor | SensiboDeviceSensor] = [] entities: list[SensiboMotionSensor | SensiboDeviceSensor] = []
nonlocal added_devices nonlocal added_devices
new_devices, remove_devices, added_devices = coordinator.get_devices( new_devices, _, new_added_devices = coordinator.get_devices(added_devices)
added_devices added_devices = new_added_devices
)
if new_devices: if new_devices:
entities.extend( entities.extend(

View File

@ -89,7 +89,8 @@ async def async_setup_entry(
def _add_remove_devices() -> None: def _add_remove_devices() -> None:
"""Handle additions of devices and sensors.""" """Handle additions of devices and sensors."""
nonlocal added_devices nonlocal added_devices
new_devices, _, added_devices = coordinator.get_devices(added_devices) new_devices, _, new_added_devices = coordinator.get_devices(added_devices)
added_devices = new_added_devices
if new_devices: if new_devices:
async_add_entities( async_add_entities(

View File

@ -56,7 +56,8 @@ async def async_setup_entry(
def _add_remove_devices() -> None: def _add_remove_devices() -> None:
"""Handle additions of devices and sensors.""" """Handle additions of devices and sensors."""
nonlocal added_devices nonlocal added_devices
new_devices, _, added_devices = coordinator.get_devices(added_devices) new_devices, _, new_added_devices = coordinator.get_devices(added_devices)
added_devices = new_added_devices
if new_devices: if new_devices:
async_add_entities( async_add_entities(

View File

@ -9,6 +9,7 @@ from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory from freezegun.api import FrozenDateTimeFactory
from pysensibo.exceptions import AuthenticationError, SensiboError from pysensibo.exceptions import AuthenticationError, SensiboError
from pysensibo.model import SensiboData from pysensibo.model import SensiboData
import pytest
from homeassistant.components.climate import HVACMode from homeassistant.components.climate import HVACMode
from homeassistant.components.sensibo.const import DOMAIN from homeassistant.components.sensibo.const import DOMAIN
@ -25,6 +26,7 @@ async def test_coordinator(
mock_client: MagicMock, mock_client: MagicMock,
get_data: tuple[SensiboData, dict[str, Any], dict[str, Any]], get_data: tuple[SensiboData, dict[str, Any], dict[str, Any]],
freezer: FrozenDateTimeFactory, freezer: FrozenDateTimeFactory,
caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
"""Test the Sensibo coordinator with errors.""" """Test the Sensibo coordinator with errors."""
config_entry = MockConfigEntry( config_entry = MockConfigEntry(
@ -87,3 +89,5 @@ async def test_coordinator(
mock_data.assert_called_once() mock_data.assert_called_once()
state = hass.states.get("climate.hallway") state = hass.states.get("climate.hallway")
assert state.state == STATE_UNAVAILABLE assert state.state == STATE_UNAVAILABLE
assert "Platform sensibo does not generate unique IDs" not in caplog.text