mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 17:04:04 -04:00
Migrate the Lyngdorf sensor platform to the lyngdorf 2.0 API (#180704)
This commit is contained in:
@@ -4,7 +4,7 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, override
|
||||
|
||||
from lyngdorf.device import Receiver
|
||||
from lyngdorf import LyngdorfReceiver
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@@ -26,8 +26,8 @@ PARALLEL_UPDATES = 0
|
||||
class LyngdorfSensorEntityDescription(SensorEntityDescription):
|
||||
"""Describe a Lyngdorf sensor entity."""
|
||||
|
||||
value_fn: Callable[[Receiver], str | None]
|
||||
options_fn: Callable[[Receiver], list[str]] | None = None
|
||||
value_fn: Callable[[LyngdorfReceiver], str | None]
|
||||
options_fn: Callable[[LyngdorfReceiver], list[str]] | None = None
|
||||
|
||||
|
||||
def _known(value: str | None, options: list[str]) -> str | None:
|
||||
@@ -52,24 +52,24 @@ MAIN_ZONE_SENSORS: tuple[LyngdorfSensorEntityDescription, ...] = (
|
||||
key="audio_input",
|
||||
translation_key="audio_input",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
value_fn=lambda r: _known(r.audio_input, r.available_audio_inputs),
|
||||
options_fn=lambda r: r.available_audio_inputs,
|
||||
value_fn=lambda r: _known(r.audio_input, r.audio_inputs),
|
||||
options_fn=lambda r: r.audio_inputs,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
LyngdorfSensorEntityDescription(
|
||||
key="video_input",
|
||||
translation_key="video_input",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
value_fn=lambda r: _known(r.video_input, r.available_video_inputs),
|
||||
options_fn=lambda r: r.available_video_inputs,
|
||||
value_fn=lambda r: _known(r.video_input, r.video_inputs),
|
||||
options_fn=lambda r: r.video_inputs,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
LyngdorfSensorEntityDescription(
|
||||
key="streaming_source",
|
||||
translation_key="streaming_source",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
value_fn=lambda r: _known(r.streaming_source, r.available_stream_types),
|
||||
options_fn=lambda r: r.available_stream_types,
|
||||
value_fn=lambda r: _known(r.streaming_source, r.stream_types),
|
||||
options_fn=lambda r: r.stream_types,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
)
|
||||
@@ -79,16 +79,20 @@ ZONE_B_SENSORS: tuple[LyngdorfSensorEntityDescription, ...] = (
|
||||
key="zone_b_audio_input",
|
||||
translation_key="zone_b_audio_input",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
value_fn=lambda r: _known(r.zone_b_audio_input, r.available_audio_inputs),
|
||||
options_fn=lambda r: r.available_audio_inputs,
|
||||
value_fn=lambda r: (
|
||||
_known(zb.audio_input, r.audio_inputs) if (zb := r.zone_b) else None
|
||||
),
|
||||
options_fn=lambda r: r.audio_inputs,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
LyngdorfSensorEntityDescription(
|
||||
key="zone_b_streaming_source",
|
||||
translation_key="zone_b_streaming_source",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
value_fn=lambda r: _known(r.zone_b_streaming_source, r.available_stream_types),
|
||||
options_fn=lambda r: r.available_stream_types,
|
||||
value_fn=lambda r: (
|
||||
_known(zb.streaming_source, r.stream_types) if (zb := r.zone_b) else None
|
||||
),
|
||||
options_fn=lambda r: r.stream_types,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
)
|
||||
@@ -131,7 +135,7 @@ class LyngdorfSensor(LyngdorfEntity, SensorEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
receiver: Receiver,
|
||||
receiver: LyngdorfReceiver,
|
||||
config_entry: LyngdorfConfigEntry,
|
||||
device_info: DeviceInfo,
|
||||
description: LyngdorfSensorEntityDescription,
|
||||
|
||||
@@ -143,8 +143,11 @@ def mock_receiver(mock_create_receiver: MagicMock) -> MagicMock:
|
||||
receiver.video_input = "hdmi"
|
||||
receiver.streaming_source = "AirPlay"
|
||||
receiver.available_audio_inputs = ["optical", "aux"]
|
||||
receiver.audio_inputs = ["optical", "aux"]
|
||||
receiver.available_video_inputs = ["hdmi"]
|
||||
receiver.video_inputs = ["hdmi"]
|
||||
receiver.available_stream_types = ["AirPlay", "DLNA"]
|
||||
receiver.stream_types = ["AirPlay", "DLNA"]
|
||||
|
||||
receiver.now_playing = None
|
||||
receiver.has_position = False
|
||||
@@ -182,6 +185,10 @@ def mock_receiver(mock_create_receiver: MagicMock) -> MagicMock:
|
||||
receiver.zone_b_source = None
|
||||
receiver.zone_b_available_sources = []
|
||||
receiver.zone_b_audio_input = "aux"
|
||||
zone_b = MagicMock(spec=ZoneB)
|
||||
zone_b.audio_input = "aux"
|
||||
zone_b.streaming_source = "DLNA"
|
||||
receiver.zone_b = zone_b
|
||||
receiver.zone_b_streaming_source = "DLNA"
|
||||
|
||||
receiver.volume = _FloatControl(-40.0, NumericRange(-99.9, 24.0, 0.1))
|
||||
|
||||
@@ -52,7 +52,7 @@ async def test_enum_sensor_ignores_unknown_device_value(
|
||||
mock_receiver: MagicMock,
|
||||
) -> None:
|
||||
"""Test an input the library could not name is reported as unknown."""
|
||||
mock_receiver.available_audio_inputs = ["optical"]
|
||||
mock_receiver.audio_inputs = ["optical"]
|
||||
mock_receiver.audio_input = "audio-37"
|
||||
|
||||
notify_receiver_update(mock_receiver)
|
||||
@@ -61,13 +61,63 @@ async def test_enum_sensor_ignores_unknown_device_value(
|
||||
assert hass.states.get("sensor.mock_lyngdorf_audio_input").state == STATE_UNKNOWN
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "attribute", "value"),
|
||||
[
|
||||
pytest.param(
|
||||
"sensor.mock_lyngdorf_video_input", "video_inputs", ["DP"], id="video"
|
||||
),
|
||||
pytest.param(
|
||||
"sensor.mock_lyngdorf_streaming_source",
|
||||
"stream_types",
|
||||
["Spotify"],
|
||||
id="stream",
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_sensors_read_the_current_lists_not_the_deprecated_aliases(
|
||||
hass: HomeAssistant,
|
||||
mock_receiver: MagicMock,
|
||||
entity_id: str,
|
||||
attribute: str,
|
||||
value: list[str],
|
||||
) -> None:
|
||||
"""Test the lists come from the 2.0 names while the aliases say otherwise."""
|
||||
setattr(mock_receiver, attribute, value)
|
||||
notify_receiver_update(mock_receiver)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(entity_id).attributes["options"] == value
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_zone_b_sensors_read_the_zone_object(
|
||||
hass: HomeAssistant,
|
||||
mock_receiver: MagicMock,
|
||||
) -> None:
|
||||
"""Test the Zone B sensors follow the zone, not the receiver aliases."""
|
||||
mock_receiver.zone_b.audio_input = "optical"
|
||||
mock_receiver.zone_b.streaming_source = "AirPlay"
|
||||
mock_receiver.zone_b_audio_input = "aux"
|
||||
mock_receiver.zone_b_streaming_source = "DLNA"
|
||||
notify_receiver_update(mock_receiver)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get("sensor.mock_lyngdorf_zone_b_audio_input").state == "optical"
|
||||
assert (
|
||||
hass.states.get("sensor.mock_lyngdorf_zone_b_streaming_source").state
|
||||
== "AirPlay"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_enum_options_follow_the_device(
|
||||
hass: HomeAssistant,
|
||||
mock_receiver: MagicMock,
|
||||
) -> None:
|
||||
"""Test enum options track the lists the device reports."""
|
||||
mock_receiver.available_audio_inputs = ["HDMI", "optical"]
|
||||
mock_receiver.audio_inputs = ["HDMI", "optical"]
|
||||
mock_receiver.audio_input = "HDMI"
|
||||
notify_receiver_update(mock_receiver)
|
||||
await hass.async_block_till_done()
|
||||
@@ -75,7 +125,7 @@ async def test_enum_options_follow_the_device(
|
||||
state = hass.states.get("sensor.mock_lyngdorf_audio_input")
|
||||
assert state.attributes["options"] == ["HDMI", "optical"]
|
||||
|
||||
mock_receiver.available_audio_inputs = ["HDMI", "optical", "ARC"]
|
||||
mock_receiver.audio_inputs = ["HDMI", "optical", "ARC"]
|
||||
notify_receiver_update(mock_receiver)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user