From 55cf3b60eb79f462865c19c576848bbbdde7b5a8 Mon Sep 17 00:00:00 2001 From: IceBotYT <34712694+IceBotYT@users.noreply.github.com> Date: Sun, 18 Aug 2024 09:57:05 -0400 Subject: [PATCH] Add light platform to Nice G.O. (#124019) * Add light platform to Nice G.O. * Update homeassistant/components/nice_go/light.py --------- Co-authored-by: Joost Lekkerkerker --- homeassistant/components/nice_go/__init__.py | 2 +- homeassistant/components/nice_go/light.py | 48 ++++++++++ homeassistant/components/nice_go/strings.json | 7 ++ tests/components/nice_go/test_light.py | 88 +++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/nice_go/light.py create mode 100644 tests/components/nice_go/test_light.py diff --git a/homeassistant/components/nice_go/__init__.py b/homeassistant/components/nice_go/__init__.py index 33c81b70966..f0bfea58b89 100644 --- a/homeassistant/components/nice_go/__init__.py +++ b/homeassistant/components/nice_go/__init__.py @@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant from .coordinator import NiceGOUpdateCoordinator _LOGGER = logging.getLogger(__name__) -PLATFORMS: list[Platform] = [Platform.COVER] +PLATFORMS: list[Platform] = [Platform.COVER, Platform.LIGHT] type NiceGOConfigEntry = ConfigEntry[NiceGOUpdateCoordinator] diff --git a/homeassistant/components/nice_go/light.py b/homeassistant/components/nice_go/light.py new file mode 100644 index 00000000000..76730ea822f --- /dev/null +++ b/homeassistant/components/nice_go/light.py @@ -0,0 +1,48 @@ +"""Nice G.O. light.""" + +from typing import Any + +from homeassistant.components.light import ColorMode, LightEntity +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from . import NiceGOConfigEntry +from .entity import NiceGOEntity + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: NiceGOConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up Nice G.O. light.""" + + coordinator = config_entry.runtime_data + + async_add_entities( + NiceGOLightEntity(coordinator, device_id, device_data.name, "light") + for device_id, device_data in coordinator.data.items() + ) + + +class NiceGOLightEntity(NiceGOEntity, LightEntity): + """Light for Nice G.O. devices.""" + + _attr_color_mode = ColorMode.ONOFF + _attr_supported_color_modes = {ColorMode.ONOFF} + _attr_translation_key = "light" + + @property + def is_on(self) -> bool: + """Return if the light is on or not.""" + return self.data.light_status + + async def async_turn_on(self, **kwargs: Any) -> None: + """Turn on the light.""" + + await self.coordinator.api.light_on(self._device_id) + + async def async_turn_off(self, **kwargs: Any) -> None: + """Turn off the light.""" + + await self.coordinator.api.light_off(self._device_id) diff --git a/homeassistant/components/nice_go/strings.json b/homeassistant/components/nice_go/strings.json index 8d21f6d9740..261f71ebcbe 100644 --- a/homeassistant/components/nice_go/strings.json +++ b/homeassistant/components/nice_go/strings.json @@ -17,6 +17,13 @@ "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" } }, + "entity": { + "light": { + "light": { + "name": "[%key:component::light::title%]" + } + } + }, "issues": { "firmware_update_required": { "title": "Firmware update required", diff --git a/tests/components/nice_go/test_light.py b/tests/components/nice_go/test_light.py new file mode 100644 index 00000000000..e1852581fe6 --- /dev/null +++ b/tests/components/nice_go/test_light.py @@ -0,0 +1,88 @@ +"""Test Nice G.O. light.""" + +from unittest.mock import AsyncMock + +from syrupy import SnapshotAssertion + +from homeassistant.components.light import ( + DOMAIN as LIGHT_DOMAIN, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.components.nice_go.const import DOMAIN +from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from . import setup_integration + +from tests.common import MockConfigEntry, load_json_object_fixture, snapshot_platform + + +async def test_data( + hass: HomeAssistant, + mock_nice_go: AsyncMock, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, + mock_config_entry: MockConfigEntry, +) -> None: + """Test that data gets parsed and returned appropriately.""" + + await setup_integration(hass, mock_config_entry, [Platform.LIGHT]) + + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) + + +async def test_turn_on( + hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry +) -> None: + """Test that turning on the light works as intended.""" + + await setup_integration(hass, mock_config_entry, [Platform.LIGHT]) + + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "light.test_garage_2_light"}, + blocking=True, + ) + + assert mock_nice_go.light_on.call_count == 1 + + +async def test_turn_off( + hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry +) -> None: + """Test that turning off the light works as intended.""" + + await setup_integration(hass, mock_config_entry, [Platform.LIGHT]) + + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.test_garage_1_light"}, + blocking=True, + ) + + assert mock_nice_go.light_off.call_count == 1 + + +async def test_update_light_state( + hass: HomeAssistant, + mock_nice_go: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test that turning off the light works as intended.""" + + await setup_integration(hass, mock_config_entry, [Platform.LIGHT]) + + assert hass.states.get("light.test_garage_1_light").state == STATE_ON + assert hass.states.get("light.test_garage_2_light").state == STATE_OFF + + device_update = load_json_object_fixture("device_state_update.json", DOMAIN) + await mock_config_entry.runtime_data.on_data(device_update) + device_update_1 = load_json_object_fixture("device_state_update_1.json", DOMAIN) + await mock_config_entry.runtime_data.on_data(device_update_1) + + assert hass.states.get("light.test_garage_1_light").state == STATE_OFF + assert hass.states.get("light.test_garage_2_light").state == STATE_ON