diff --git a/homeassistant/components/lunatone/__init__.py b/homeassistant/components/lunatone/__init__.py index 5a2f28674755dd..dde1f64bb4e382 100644 --- a/homeassistant/components/lunatone/__init__.py +++ b/homeassistant/components/lunatone/__init__.py @@ -3,7 +3,14 @@ import logging from typing import Final -from lunatone_rest_api_client import Auth, DALIBroadcast, Devices, Info, Sensors +from lunatone_rest_api_client import ( + Auth, + DALIBroadcast, + DALIScan, + Devices, + Info, + Sensors, +) from homeassistant.const import CONF_URL, Platform from homeassistant.core import HomeAssistant @@ -18,11 +25,16 @@ LunatoneData, LunatoneDevicesDataUpdateCoordinator, LunatoneInfoDataUpdateCoordinator, + LunatoneScanDataUpdateCoordinator, LunatoneSensorsDataUpdateCoordinator, ) _LOGGER = logging.getLogger(__name__) -PLATFORMS: Final[list[Platform]] = [Platform.LIGHT, Platform.SENSOR] +PLATFORMS: Final[list[Platform]] = [ + Platform.BINARY_SENSOR, + Platform.LIGHT, + Platform.SENSOR, +] async def _update_unique_id( @@ -70,6 +82,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: LunatoneConfigEntry) -> """Set up Lunatone from a config entry.""" auth_api = Auth(async_get_clientsession(hass), entry.data[CONF_URL]) info_api = Info(auth_api) + dali_scan_api = DALIScan(auth_api) devices_api = Devices(info_api) sensors_api = Sensors(auth_api) @@ -110,6 +123,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: LunatoneConfigEntry) -> coordinator_sensors = LunatoneSensorsDataUpdateCoordinator(hass, entry, sensors_api) await coordinator_sensors.async_config_entry_first_refresh() + coordinator_scan = LunatoneScanDataUpdateCoordinator(hass, entry, dali_scan_api) + await coordinator_scan.async_config_entry_first_refresh() + dali_line_broadcasts = [ DALIBroadcast(auth_api, int(line)) for line in coordinator_info.data.lines ] @@ -118,6 +134,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: LunatoneConfigEntry) -> coordinator_info, coordinator_devices, coordinator_sensors, + coordinator_scan, dali_line_broadcasts, ) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/lunatone/binary_sensor.py b/homeassistant/components/lunatone/binary_sensor.py new file mode 100644 index 00000000000000..c05ef6cc616274 --- /dev/null +++ b/homeassistant/components/lunatone/binary_sensor.py @@ -0,0 +1,65 @@ +"""Platform for Lunatone binary sensor integration.""" + +from typing import override + +from homeassistant.components.binary_sensor import ( + BinarySensorDeviceClass, + BinarySensorEntity, +) +from homeassistant.const import EntityCategory +from homeassistant.core import HomeAssistant +from homeassistant.helpers.device_registry import DeviceInfo +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from .const import DOMAIN +from .coordinator import LunatoneConfigEntry, LunatoneScanDataUpdateCoordinator + +PARALLEL_UPDATES = 0 + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: LunatoneConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, +) -> None: + """Set up Lunatone binary sensors from the config entry.""" + coordinator_scan = config_entry.runtime_data.coordinator_scan + + assert config_entry.unique_id is not None + + async_add_entities( + [LunatoneDALIScanStatus(coordinator_scan, config_entry.unique_id)] + ) + + +class LunatoneDALIScanStatus( + CoordinatorEntity[LunatoneScanDataUpdateCoordinator], BinarySensorEntity +): + """Representation of a Lunatone DALI scan status.""" + + _attr_device_class = BinarySensorDeviceClass.RUNNING + _attr_entity_category = EntityCategory.DIAGNOSTIC + _attr_has_entity_name = True + _attr_translation_key = "scan_status" + + def __init__( + self, + coordinator: LunatoneScanDataUpdateCoordinator, + config_entry_unique_id: str, + ) -> None: + """Initialize a Lunatone DALI scan status.""" + super().__init__(coordinator) + + self._config_entry_unique_id = config_entry_unique_id + + self._attr_unique_id = f"{config_entry_unique_id}-scan-progress" + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, self._config_entry_unique_id)}, + ) + + @property + @override + def is_on(self) -> bool: + """Return true if the DALI scan is on.""" + return self.coordinator.dali_scan_api.is_busy diff --git a/homeassistant/components/lunatone/coordinator.py b/homeassistant/components/lunatone/coordinator.py index f5a591e5f2966b..6170309d09110e 100644 --- a/homeassistant/components/lunatone/coordinator.py +++ b/homeassistant/components/lunatone/coordinator.py @@ -8,13 +8,14 @@ import aiohttp from lunatone_rest_api_client import ( DALIBroadcast, + DALIScan, Device, Devices, Info, Sensor, Sensors, ) -from lunatone_rest_api_client.models import InfoData +from lunatone_rest_api_client.models import InfoData, ScanData from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -24,9 +25,10 @@ _LOGGER = logging.getLogger(__name__) -DEFAULT_INFO_SCAN_INTERVAL = timedelta(seconds=60) -DEFAULT_DEVICES_SCAN_INTERVAL = timedelta(seconds=10) -DEFAULT_SENSORS_SCAN_INTERVAL = timedelta(seconds=30) +DEFAULT_INFO_UPDATE_INTERVAL = timedelta(seconds=60) +DEFAULT_DEVICES_UPDATE_INTERVAL = timedelta(seconds=10) +DEFAULT_SENSORS_UPDATE_INTERVAL = timedelta(seconds=30) +DEFAULT_SCAN_UPDATE_INTERVAL = timedelta(seconds=10) @dataclass @@ -36,6 +38,7 @@ class LunatoneData: coordinator_info: LunatoneInfoDataUpdateCoordinator coordinator_devices: LunatoneDevicesDataUpdateCoordinator coordinator_sensors: LunatoneSensorsDataUpdateCoordinator + coordinator_scan: LunatoneScanDataUpdateCoordinator dali_line_broadcasts: list[DALIBroadcast] @@ -57,7 +60,7 @@ def __init__( config_entry=config_entry, name=f"{DOMAIN}-info", always_update=False, - update_interval=DEFAULT_INFO_SCAN_INTERVAL, + update_interval=DEFAULT_INFO_UPDATE_INTERVAL, ) self.info_api = info_api @@ -94,7 +97,7 @@ def __init__( config_entry=config_entry, name=f"{DOMAIN}-devices", always_update=False, - update_interval=DEFAULT_DEVICES_SCAN_INTERVAL, + update_interval=DEFAULT_DEVICES_UPDATE_INTERVAL, ) self.devices_api = devices_api @@ -131,7 +134,7 @@ def __init__( config_entry=config_entry, name=f"{DOMAIN}-sensors", always_update=False, - update_interval=DEFAULT_SENSORS_SCAN_INTERVAL, + update_interval=DEFAULT_SENSORS_UPDATE_INTERVAL, ) self.sensors_api = sensors_api @@ -149,3 +152,46 @@ async def _async_update_data(self) -> dict[int, Sensor]: if self.sensors_api.data is None: raise UpdateFailed("Did not receive sensors data from Lunatone REST API") return {sensor.id: sensor for sensor in self.sensors_api.sensors} + + +class LunatoneScanDataUpdateCoordinator(DataUpdateCoordinator[ScanData]): + """Data update coordinator for Lunatone scan.""" + + config_entry: LunatoneConfigEntry + + def __init__( + self, + hass: HomeAssistant, + config_entry: LunatoneConfigEntry, + dali_scan_api: DALIScan, + ) -> None: + """Initialize the coordinator.""" + super().__init__( + hass, + _LOGGER, + config_entry=config_entry, + name=f"{DOMAIN}-scan", + always_update=False, + update_interval=DEFAULT_SCAN_UPDATE_INTERVAL, + ) + self.dali_scan_api = dali_scan_api + + @override + async def _async_update_data(self) -> ScanData: + """Update scan data.""" + try: + await self.dali_scan_api.async_update() + except aiohttp.ClientConnectionError as ex: + raise UpdateFailed( + "Unable to retrieve scan data from Lunatone REST API" + ) from ex + + if self.dali_scan_api.data is None: + raise UpdateFailed("Did not receive scan data from Lunatone REST API") + + update_interval = DEFAULT_SCAN_UPDATE_INTERVAL + if self.dali_scan_api.is_busy: + update_interval = timedelta(seconds=1) + self.update_interval = update_interval + + return self.dali_scan_api.data diff --git a/homeassistant/components/lunatone/strings.json b/homeassistant/components/lunatone/strings.json index ff57187e1e16c1..2d2b6b20800a0e 100644 --- a/homeassistant/components/lunatone/strings.json +++ b/homeassistant/components/lunatone/strings.json @@ -37,6 +37,13 @@ } } }, + "entity": { + "binary_sensor": { + "scan_status": { + "name": "DALI scan" + } + } + }, "exceptions": { "missing_device_info": { "message": "Unable to read device information. Please verify the device's network connection." diff --git a/tests/components/lunatone/conftest.py b/tests/components/lunatone/conftest.py index ba5e5f364b9c13..82813f857cc68f 100644 --- a/tests/components/lunatone/conftest.py +++ b/tests/components/lunatone/conftest.py @@ -4,7 +4,7 @@ from unittest.mock import AsyncMock, PropertyMock, patch from lunatone_rest_api_client import Device, Devices, Info, Sensor, Sensors -from lunatone_rest_api_client.models import InfoData, SensorsData +from lunatone_rest_api_client.models import InfoData, ScanData, ScanState, SensorsData import pytest from homeassistant.components.lunatone.config_flow import LunatoneConfigFlow @@ -161,6 +161,29 @@ def _set_data(data: SensorsData) -> None: yield sensors +@pytest.fixture +def mock_lunatone_scan() -> Generator[AsyncMock]: + """Mock a Lunatone DALI scan object.""" + with ( + patch( + "homeassistant.components.lunatone.DALIScan", + autospec=True, + ) as mock_dali_scan, + patch( + "homeassistant.components.lunatone.coordinator.DALIScan", + new=mock_dali_scan, + ), + ): + scan = mock_dali_scan.return_value + scan.data = ScanData() + type(scan).is_busy = PropertyMock( + side_effect=lambda: ( + scan.data.status in {ScanState.ADDRESSING, ScanState.IN_PROGRESS} + ) + ) + yield scan + + @pytest.fixture def mock_config_entry() -> MockConfigEntry: """Return the default mocked config entry.""" diff --git a/tests/components/lunatone/snapshots/test_binary_sensor.ambr b/tests/components/lunatone/snapshots/test_binary_sensor.ambr new file mode 100644 index 00000000000000..c6c2547af67049 --- /dev/null +++ b/tests/components/lunatone/snapshots/test_binary_sensor.ambr @@ -0,0 +1,52 @@ +# serializer version: 1 +# name: test_setup[binary_sensor.test_dali_scan-entry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.test_dali_scan', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'DALI scan', + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'DALI scan', + 'platform': 'lunatone', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'scan_status', + 'unique_id': 'be37ca9c47c24498a38bc62c7c711840-scan-progress', + 'unit_of_measurement': None, + }) +# --- +# name: test_setup[binary_sensor.test_dali_scan-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'running', + : 'Test DALI scan', + }), + 'context': , + 'entity_id': 'binary_sensor.test_dali_scan', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }) +# --- diff --git a/tests/components/lunatone/test_binary_sensor.py b/tests/components/lunatone/test_binary_sensor.py new file mode 100644 index 00000000000000..ae9a13025e4de2 --- /dev/null +++ b/tests/components/lunatone/test_binary_sensor.py @@ -0,0 +1,76 @@ +"""Tests for the binary sensors provided by the Lunatone integration.""" + +from datetime import timedelta +from unittest.mock import AsyncMock + +from lunatone_rest_api_client.models import ScanData, ScanState +from syrupy.assertion import SnapshotAssertion + +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from . import setup_integration + +from tests.common import MockConfigEntry + + +async def test_setup( + hass: HomeAssistant, + mock_lunatone_info: AsyncMock, + mock_lunatone_devices: AsyncMock, + mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, + mock_config_entry: MockConfigEntry, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, +) -> None: + """Test the Lunatone binary sensor setup.""" + await setup_integration(hass, mock_config_entry) + + entities = hass.states.async_all(Platform.BINARY_SENSOR) + for entity_state in entities: + entity_entry = entity_registry.async_get(entity_state.entity_id) + assert entity_entry + assert entity_entry == snapshot(name=f"{entity_entry.entity_id}-entry") + assert entity_state == snapshot(name=f"{entity_entry.entity_id}-state") + + +async def test_sensor_value_update( + hass: HomeAssistant, + mock_lunatone_info: AsyncMock, + mock_lunatone_devices: AsyncMock, + mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test the Lunatone DALI scan status value update.""" + scan_states = iter((ScanState.ADDRESSING, ScanState.DONE)) + + await setup_integration(hass, mock_config_entry) + + coordinator = mock_config_entry.runtime_data.coordinator_scan + + async def fake_update(): + scan_state = next(scan_states) + mock_lunatone_scan.data = ScanData(status=scan_state) + + mock_lunatone_scan.async_update.side_effect = fake_update + + entities = hass.states.async_all(Platform.BINARY_SENSOR) + assert entities[0].state == "off" + assert coordinator.update_interval == timedelta(seconds=10) + + await coordinator.async_refresh() + await hass.async_block_till_done() + + entities = hass.states.async_all(Platform.BINARY_SENSOR) + assert entities[0].state == "on" + assert coordinator.update_interval == timedelta(seconds=1) + + await coordinator.async_refresh() + await hass.async_block_till_done() + + entities = hass.states.async_all(Platform.BINARY_SENSOR) + assert entities[0].state == "off" + assert coordinator.update_interval == timedelta(seconds=10) diff --git a/tests/components/lunatone/test_config_flow.py b/tests/components/lunatone/test_config_flow.py index 3db320d2a50757..16fc432f531f4f 100644 --- a/tests/components/lunatone/test_config_flow.py +++ b/tests/components/lunatone/test_config_flow.py @@ -158,6 +158,7 @@ async def test_zeroconf_flow( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, ) -> None: """Test zeroconf flow.""" result = await hass.config_entries.flow.async_init( @@ -180,6 +181,7 @@ async def test_zeroconf_flow_abort_duplicate( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test zeroconf flow aborts with duplicate.""" diff --git a/tests/components/lunatone/test_diagnostics.py b/tests/components/lunatone/test_diagnostics.py index 044ff2d30af590..fbf0e42995bbe7 100644 --- a/tests/components/lunatone/test_diagnostics.py +++ b/tests/components/lunatone/test_diagnostics.py @@ -19,6 +19,7 @@ async def test_config_entry_diagnostics( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, snapshot: SnapshotAssertion, ) -> None: diff --git a/tests/components/lunatone/test_init.py b/tests/components/lunatone/test_init.py index 0f644d905ea80f..9c0b5275b3fc89 100644 --- a/tests/components/lunatone/test_init.py +++ b/tests/components/lunatone/test_init.py @@ -20,6 +20,7 @@ async def test_load_unload_config_entry( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, device_registry: dr.DeviceRegistry, ) -> None: @@ -50,6 +51,7 @@ async def test_config_entry_not_ready_info_api_fail( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test config entry not ready due to info API failure.""" @@ -74,6 +76,7 @@ async def test_config_entry_not_ready_devices_api_fail( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test config entry not ready due to devices API failure.""" @@ -100,6 +103,7 @@ async def test_config_entry_not_ready_sensors_api_fail( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test config entry not ready due to sensors API failure.""" @@ -123,6 +127,37 @@ async def test_config_entry_not_ready_sensors_api_fail( assert mock_config_entry.state is ConfigEntryState.LOADED +async def test_config_entry_not_ready_scan_api_fail( + hass: HomeAssistant, + mock_lunatone_info: AsyncMock, + mock_lunatone_devices: AsyncMock, + mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test config entry not ready due to sensors API failure.""" + mock_lunatone_scan.async_update.side_effect = aiohttp.ClientConnectionError() + + await setup_integration(hass, mock_config_entry) + + mock_lunatone_info.async_update.assert_called_once() + mock_lunatone_devices.async_update.assert_called_once() + mock_lunatone_sensors.async_update.assert_called_once() + mock_lunatone_scan.async_update.assert_called_once() + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY + + mock_lunatone_scan.async_update.side_effect = None + + await hass.config_entries.async_reload(mock_config_entry.entry_id) + await hass.async_block_till_done() + + mock_lunatone_info.async_update.assert_called() + mock_lunatone_devices.async_update.assert_called() + mock_lunatone_sensors.async_update.assert_called() + mock_lunatone_scan.async_update.assert_called() + assert mock_config_entry.state is ConfigEntryState.LOADED + + async def test_config_entry_not_ready_no_info_data( hass: HomeAssistant, mock_lunatone_info: AsyncMock, @@ -172,6 +207,26 @@ async def test_config_entry_not_ready_no_sensors_data( assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY +async def test_config_entry_not_ready_no_dali_scan_data( + hass: HomeAssistant, + mock_lunatone_info: AsyncMock, + mock_lunatone_devices: AsyncMock, + mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test the Lunatone configuration entry not ready due to missing DALI scan data.""" + mock_lunatone_scan.data = None + + await setup_integration(hass, mock_config_entry) + + mock_lunatone_info.async_update.assert_called_once() + mock_lunatone_devices.async_update.assert_called_once() + mock_lunatone_sensors.async_update.assert_called_once() + mock_lunatone_scan.async_update.assert_called_once() + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY + + async def test_config_entry_not_ready_no_serial_number( hass: HomeAssistant, mock_lunatone_info: AsyncMock, @@ -192,6 +247,7 @@ async def test_config_entry_unique_id_update( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, diff --git a/tests/components/lunatone/test_light.py b/tests/components/lunatone/test_light.py index 4ccbf1964335b5..0b88287f49eb04 100644 --- a/tests/components/lunatone/test_light.py +++ b/tests/components/lunatone/test_light.py @@ -35,6 +35,7 @@ async def test_setup( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, @@ -56,6 +57,7 @@ async def test_turn_on_off( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test the light can be turned on and off.""" @@ -98,6 +100,7 @@ async def test_turn_on_off_with_brightness( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test the light can be turned on with brightness.""" @@ -158,6 +161,7 @@ async def test_turn_on_off_broadcast( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_lunatone_dali_broadcast: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: @@ -202,6 +206,7 @@ async def test_line_broadcast_available_status( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_lunatone_dali_broadcast: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: @@ -234,6 +239,7 @@ async def test_line_broadcast_line_present( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_lunatone_dali_broadcast: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: @@ -254,6 +260,7 @@ async def test_turn_on_with_color_temperature( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, color_temp_kelvin: int, ) -> None: @@ -294,6 +301,7 @@ async def test_turn_on_with_rgb_color( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, rgb_color: tuple[int, int, int], ) -> None: @@ -336,6 +344,7 @@ async def test_turn_on_with_rgbw_color( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, rgbw_color: tuple[int, int, int, int], ) -> None: diff --git a/tests/components/lunatone/test_sensor.py b/tests/components/lunatone/test_sensor.py index a630aa8fc06a02..cccfb2f58fa494 100644 --- a/tests/components/lunatone/test_sensor.py +++ b/tests/components/lunatone/test_sensor.py @@ -21,6 +21,7 @@ async def test_setup( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, entity_registry: er.EntityRegistry, snapshot: SnapshotAssertion, @@ -41,6 +42,7 @@ async def test_sensor_value_update( mock_lunatone_info: AsyncMock, mock_lunatone_devices: AsyncMock, mock_lunatone_sensors: AsyncMock, + mock_lunatone_scan: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, ) -> None: