From ebd12dcda4c954fbfe18cd3265f7172796f7a136 Mon Sep 17 00:00:00 2001 From: Alex Fishlock Date: Mon, 3 Aug 2026 22:10:31 +0100 Subject: [PATCH] Bump lyngdorf to 1.4.0 (#177685) --- homeassistant/components/lyngdorf/__init__.py | 39 ++++++++++--------- .../components/lyngdorf/manifest.json | 2 +- .../components/lyngdorf/media_player.py | 19 +++++---- homeassistant/components/lyngdorf/models.py | 2 +- requirements_all.txt | 2 +- tests/components/lyngdorf/test_init.py | 23 +++++++++++ .../components/lyngdorf/test_media_player.py | 24 +++++++++++- 7 files changed, 80 insertions(+), 31 deletions(-) diff --git a/homeassistant/components/lyngdorf/__init__.py b/homeassistant/components/lyngdorf/__init__.py index 3cb1a64188eb..7237091935e1 100644 --- a/homeassistant/components/lyngdorf/__init__.py +++ b/homeassistant/components/lyngdorf/__init__.py @@ -71,25 +71,26 @@ async def async_setup_entry( model=lyngdorf_model.model_name, ) - # Register the main device up front so Zone B can resolve its via_device_id. - device_registry = dr.async_get(hass) - device_registry.async_get_or_create( - config_entry_id=config_entry.entry_id, **device_info - ) - - zone_b_device_info = DeviceInfo( - identifiers={(DOMAIN, f"{config_entry.unique_id}_zone_b")}, - manufacturer=lyngdorf_model.manufacturer, - serial_number=serial, - model=lyngdorf_model.model_name, - translation_key="zone_b", - translation_placeholders={"device_name": config_entry.title}, - via_device_id=async_get_device_id_by_identifier( - hass, - (DOMAIN, config_entry.unique_id), - config_entry_id=config_entry.entry_id, - ), - ) + zone_b_device_info: DeviceInfo | None = None + if lyngdorf_model.has_zone_b_feature(): + # Register the main device up front so Zone B can resolve its via_device_id. + device_registry = dr.async_get(hass) + device_registry.async_get_or_create( + config_entry_id=config_entry.entry_id, **device_info + ) + zone_b_device_info = DeviceInfo( + identifiers={(DOMAIN, f"{config_entry.unique_id}_zone_b")}, + manufacturer=lyngdorf_model.manufacturer, + serial_number=serial, + model=lyngdorf_model.model_name, + translation_key="zone_b", + translation_placeholders={"device_name": config_entry.title}, + via_device_id=async_get_device_id_by_identifier( + hass, + (DOMAIN, config_entry.unique_id), + config_entry_id=config_entry.entry_id, + ), + ) config_entry.runtime_data = LyngdorfRuntimeData( receiver=receiver, diff --git a/homeassistant/components/lyngdorf/manifest.json b/homeassistant/components/lyngdorf/manifest.json index c4144acf1011..0cd429b057d5 100644 --- a/homeassistant/components/lyngdorf/manifest.json +++ b/homeassistant/components/lyngdorf/manifest.json @@ -9,7 +9,7 @@ "iot_class": "local_push", "loggers": ["lyngdorf", "async_upnp_client"], "quality_scale": "silver", - "requirements": ["lyngdorf==1.3.3"], + "requirements": ["lyngdorf==1.4.0"], "ssdp": [ { "deviceType": "urn:schemas-upnp-org:device:MediaRenderer:2", diff --git a/homeassistant/components/lyngdorf/media_player.py b/homeassistant/components/lyngdorf/media_player.py index dd764c9d0fec..aad57f617815 100644 --- a/homeassistant/components/lyngdorf/media_player.py +++ b/homeassistant/components/lyngdorf/media_player.py @@ -51,16 +51,19 @@ async def async_setup_entry( """Set up the receiver from a config entry.""" runtime_data = config_entry.runtime_data - async_add_entities( - [ - LyngdorfMainDevice( - runtime_data.receiver, config_entry, runtime_data.device_info - ), + entities: list[LyngdorfDevice] = [ + LyngdorfMainDevice( + runtime_data.receiver, config_entry, runtime_data.device_info + ) + ] + if runtime_data.zone_b_device_info is not None: + entities.append( LyngdorfZoneBDevice( runtime_data.receiver, config_entry, runtime_data.zone_b_device_info - ), - ] - ) + ) + ) + + async_add_entities(entities) def _to_ha_volume(volume_db: float) -> float: diff --git a/homeassistant/components/lyngdorf/models.py b/homeassistant/components/lyngdorf/models.py index 26e2f84b027a..879cca55c27e 100644 --- a/homeassistant/components/lyngdorf/models.py +++ b/homeassistant/components/lyngdorf/models.py @@ -14,7 +14,7 @@ class LyngdorfRuntimeData: receiver: Receiver device_info: DeviceInfo - zone_b_device_info: DeviceInfo + zone_b_device_info: DeviceInfo | None type LyngdorfConfigEntry = ConfigEntry[LyngdorfRuntimeData] diff --git a/requirements_all.txt b/requirements_all.txt index 860229c36c01..88ce86181342 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1531,7 +1531,7 @@ lw12==0.9.2 lxml==6.1.1 # homeassistant.components.lyngdorf -lyngdorf==1.3.3 +lyngdorf==1.4.0 # homeassistant.components.matrix matrix-nio==0.26.0 diff --git a/tests/components/lyngdorf/test_init.py b/tests/components/lyngdorf/test_init.py index 27edd15e4f24..6719d596f5a0 100644 --- a/tests/components/lyngdorf/test_init.py +++ b/tests/components/lyngdorf/test_init.py @@ -127,3 +127,26 @@ async def test_mac_connection_registered_when_serial_is_mac( value for kind, value in device.connections if kind == dr.CONNECTION_NETWORK_MAC } assert mac_connections == expected_mac_connections + + +@pytest.mark.usefixtures("mock_receiver") +async def test_no_zone_b_device_for_model_without_zone_b( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + device_registry: dr.DeviceRegistry, +) -> None: + """Test no Zone B device is created for a model without Zone B.""" + mock_config_entry.add_to_hass(hass) + + with patch( + "homeassistant.components.lyngdorf.lookup_receiver_model", + return_value=LyngdorfModel.TDAI_3400, + ): + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert mock_config_entry.state is ConfigEntryState.LOADED + device = device_registry.async_get_device( + identifiers={(DOMAIN, f"{mock_config_entry.unique_id}_zone_b")} + ) + assert device is None diff --git a/tests/components/lyngdorf/test_media_player.py b/tests/components/lyngdorf/test_media_player.py index 8d9bcd84092b..2915f55483ed 100644 --- a/tests/components/lyngdorf/test_media_player.py +++ b/tests/components/lyngdorf/test_media_player.py @@ -1,7 +1,8 @@ """Tests for the Lyngdorf media player platform.""" -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch +from lyngdorf.const import LyngdorfModel import pytest from syrupy.assertion import SnapshotAssertion @@ -46,6 +47,27 @@ async def test_entities( await snapshot_platform(hass, entity_registry, snapshot, init_integration.entry_id) +@pytest.mark.usefixtures("mock_receiver") +async def test_no_zone_b_entity_for_model_without_zone_b( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + entity_registry: er.EntityRegistry, +) -> None: + """Test no Zone B media player entity is created for a model without Zone B.""" + mock_config_entry.add_to_hass(hass) + + with patch( + "homeassistant.components.lyngdorf.lookup_receiver_model", + return_value=LyngdorfModel.TDAI_3400, + ): + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert hass.states.get(ZONE_B) is None + assert entity_registry.async_get(ZONE_B) is None + assert hass.states.get(MAIN_ZONE) is not None + + @pytest.mark.parametrize( ("entity_id", "service", "attr", "expected"), [