From f6c097d8319975dcba95f77094fe351ae8e394e8 Mon Sep 17 00:00:00 2001 From: IceBotYT <34712694+IceBotYT@users.noreply.github.com> Date: Mon, 19 Aug 2024 02:32:50 +0000 Subject: [PATCH 1/6] Add switch platform to Nice G.O. --- homeassistant/components/nice_go/__init__.py | 2 +- .../components/nice_go/coordinator.py | 3 ++ homeassistant/components/nice_go/strings.json | 5 ++ homeassistant/components/nice_go/switch.py | 50 +++++++++++++++++++ .../nice_go/fixtures/get_all_barriers.json | 2 +- tests/components/nice_go/test_init.py | 2 +- tests/components/nice_go/test_switch.py | 37 ++++++++++++++ 7 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 homeassistant/components/nice_go/switch.py create mode 100644 tests/components/nice_go/test_switch.py diff --git a/homeassistant/components/nice_go/__init__.py b/homeassistant/components/nice_go/__init__.py index f0bfea58b89170..bf8dbfcaecdc0e 100644 --- a/homeassistant/components/nice_go/__init__.py +++ b/homeassistant/components/nice_go/__init__.py @@ -11,7 +11,7 @@ from .coordinator import NiceGOUpdateCoordinator _LOGGER = logging.getLogger(__name__) -PLATFORMS: list[Platform] = [Platform.COVER, Platform.LIGHT] +PLATFORMS: list[Platform] = [Platform.COVER, Platform.LIGHT, Platform.SWITCH] type NiceGOConfigEntry = ConfigEntry[NiceGOUpdateCoordinator] diff --git a/homeassistant/components/nice_go/coordinator.py b/homeassistant/components/nice_go/coordinator.py index 196ed0a211c256..323e0a08fe84ee 100644 --- a/homeassistant/components/nice_go/coordinator.py +++ b/homeassistant/components/nice_go/coordinator.py @@ -46,6 +46,7 @@ class NiceGODevice: light_status: bool fw_version: str connected: bool + vacation_mode: bool class NiceGOUpdateCoordinator(DataUpdateCoordinator[dict[str, NiceGODevice]]): @@ -105,6 +106,7 @@ async def _parse_barrier(self, barrier_state: BarrierState) -> NiceGODevice | No connected = barrier_state.connectionState.connected else: connected = False + vacation_mode = barrier_state.reported["vcnMode"] return NiceGODevice( id=device_id, @@ -113,6 +115,7 @@ async def _parse_barrier(self, barrier_state: BarrierState) -> NiceGODevice | No light_status=light_status, fw_version=fw_version, connected=connected, + vacation_mode=vacation_mode, ) async def _async_update_data(self) -> dict[str, NiceGODevice]: diff --git a/homeassistant/components/nice_go/strings.json b/homeassistant/components/nice_go/strings.json index 261f71ebcbef2f..7f2ea1512ddc32 100644 --- a/homeassistant/components/nice_go/strings.json +++ b/homeassistant/components/nice_go/strings.json @@ -22,6 +22,11 @@ "light": { "name": "[%key:component::light::title%]" } + }, + "switch": { + "vacation_mode": { + "name": "Vacation mode" + } } }, "issues": { diff --git a/homeassistant/components/nice_go/switch.py b/homeassistant/components/nice_go/switch.py new file mode 100644 index 00000000000000..d0089b24333049 --- /dev/null +++ b/homeassistant/components/nice_go/switch.py @@ -0,0 +1,50 @@ +"""Nice G.O. switch platform.""" + +from __future__ import annotations + +import logging +from typing import Any + +from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from . import NiceGOConfigEntry +from .entity import NiceGOEntity + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: NiceGOConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up Nice G.O. cover.""" + coordinator = config_entry.runtime_data + + async_add_entities( + NiceGOSwitchEntity(coordinator, device_id, device_data.name, "switch") + for device_id, device_data in coordinator.data.items() + ) + + +class NiceGOSwitchEntity(NiceGOEntity, SwitchEntity): + """Representation of a Nice G.O. switch.""" + + _attr_device_class = SwitchDeviceClass.SWITCH + _attr_icon = "mdi:beach" + _attr_translation_key = "vacation_mode" + + @property + def is_on(self) -> bool: + """Return if switch is on.""" + return self.data.vacation_mode + + async def async_turn_on(self, **kwargs: Any) -> None: + """Turn the switch on.""" + await self.coordinator.api.vacation_mode_on(self.data.id) + + async def async_turn_off(self, **kwargs: Any) -> None: + """Turn the switch off.""" + await self.coordinator.api.vacation_mode_off(self.data.id) diff --git a/tests/components/nice_go/fixtures/get_all_barriers.json b/tests/components/nice_go/fixtures/get_all_barriers.json index 481c73d91a8bf7..adb0fb4bacde7b 100644 --- a/tests/components/nice_go/fixtures/get_all_barriers.json +++ b/tests/components/nice_go/fixtures/get_all_barriers.json @@ -49,7 +49,7 @@ "migrationStatus": "DONE", "deviceId": "2", "lightStatus": "0,100", - "vcnMode": false, + "vcnMode": true, "deviceFwVersion": "1.2.3.4.5.6", "barrierStatus": "1,100,0,0,-1,0,3,0" }, diff --git a/tests/components/nice_go/test_init.py b/tests/components/nice_go/test_init.py index d6877d72724273..249622d23b0ecb 100644 --- a/tests/components/nice_go/test_init.py +++ b/tests/components/nice_go/test_init.py @@ -275,7 +275,7 @@ async def test_no_connection_state( "item": { "deviceId": "1", "desired": '{"key": "value"}', - "reported": '{"displayName":"Test Garage 1", "migrationStatus":"DONE", "barrierStatus": "1,100,0", "deviceFwVersion": "1.0.0", "lightStatus": "1,100"}', + "reported": '{"displayName":"Test Garage 1", "migrationStatus":"DONE", "barrierStatus": "1,100,0", "deviceFwVersion": "1.0.0", "lightStatus": "1,100", "vcnMode": false}', "connectionState": None, "version": None, "timestamp": None, diff --git a/tests/components/nice_go/test_switch.py b/tests/components/nice_go/test_switch.py new file mode 100644 index 00000000000000..f9432010cd4b1a --- /dev/null +++ b/tests/components/nice_go/test_switch.py @@ -0,0 +1,37 @@ +"""Nice G.O. switch tests.""" + +from unittest.mock import AsyncMock + +from homeassistant.core import HomeAssistant + +from . import setup_integration + +from tests.common import MockConfigEntry + + +async def test_turn_on( + hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry +) -> None: + """Test turn on switch.""" + await setup_integration(hass, mock_config_entry, ["switch"]) + await hass.services.async_call( + "switch", + "turn_on", + {"entity_id": "switch.test_garage_1_vacation_mode"}, + blocking=True, + ) + mock_nice_go.vacation_mode_on.assert_called_once_with("1") + + +async def test_turn_off( + hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry +) -> None: + """Test turn off switch.""" + await setup_integration(hass, mock_config_entry, ["switch"]) + await hass.services.async_call( + "switch", + "turn_off", + {"entity_id": "switch.test_garage_2_vacation_mode"}, + blocking=True, + ) + mock_nice_go.vacation_mode_off.assert_called_once_with("2") From 190d609ef05c39a4fc298f144faa13cc2e05e033 Mon Sep 17 00:00:00 2001 From: IceBotYT <34712694+IceBotYT@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:31:03 +0000 Subject: [PATCH 2/6] Replace cover with switch in switch.py --- homeassistant/components/nice_go/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/nice_go/switch.py b/homeassistant/components/nice_go/switch.py index d0089b24333049..5dd57aafb8fb5f 100644 --- a/homeassistant/components/nice_go/switch.py +++ b/homeassistant/components/nice_go/switch.py @@ -20,7 +20,7 @@ async def async_setup_entry( config_entry: NiceGOConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: - """Set up Nice G.O. cover.""" + """Set up Nice G.O. switch.""" coordinator = config_entry.runtime_data async_add_entities( From f48069c4d9ea3464bb2eb52dccd2f20c21810634 Mon Sep 17 00:00:00 2001 From: IceBotYT <34712694+IceBotYT@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:37:48 +0000 Subject: [PATCH 3/6] Use icon translations --- homeassistant/components/nice_go/icons.json | 9 +++++++++ homeassistant/components/nice_go/switch.py | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/nice_go/icons.json diff --git a/homeassistant/components/nice_go/icons.json b/homeassistant/components/nice_go/icons.json new file mode 100644 index 00000000000000..fdce7c43e242c1 --- /dev/null +++ b/homeassistant/components/nice_go/icons.json @@ -0,0 +1,9 @@ +{ + "entity": { + "switch": { + "vacation_mode": { + "default": "mdi:beach" + } + } + } +} diff --git a/homeassistant/components/nice_go/switch.py b/homeassistant/components/nice_go/switch.py index 5dd57aafb8fb5f..e7290aabdd6a3e 100644 --- a/homeassistant/components/nice_go/switch.py +++ b/homeassistant/components/nice_go/switch.py @@ -33,7 +33,6 @@ class NiceGOSwitchEntity(NiceGOEntity, SwitchEntity): """Representation of a Nice G.O. switch.""" _attr_device_class = SwitchDeviceClass.SWITCH - _attr_icon = "mdi:beach" _attr_translation_key = "vacation_mode" @property From e746be2381d61d9ff024945940acb35dec585226 Mon Sep 17 00:00:00 2001 From: IceBotYT <34712694+IceBotYT@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:59:30 +0000 Subject: [PATCH 4/6] Fix tests --- tests/components/nice_go/snapshots/test_diagnostics.ambr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/components/nice_go/snapshots/test_diagnostics.ambr b/tests/components/nice_go/snapshots/test_diagnostics.ambr index f79b0607ce2bfa..abd3b3103d1d71 100644 --- a/tests/components/nice_go/snapshots/test_diagnostics.ambr +++ b/tests/components/nice_go/snapshots/test_diagnostics.ambr @@ -9,6 +9,7 @@ 'id': '1', 'light_status': True, 'name': 'Test Garage 1', + 'vacation_mode': False, }), '2': dict({ 'barrier_status': 'open', @@ -17,6 +18,7 @@ 'id': '2', 'light_status': False, 'name': 'Test Garage 2', + 'vacation_mode': True, }), }), 'entry': dict({ From 0ce0063eb6bd32932fb812089913f1217d6246f0 Mon Sep 17 00:00:00 2001 From: IceBotYT <34712694+IceBotYT@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:12:09 +0000 Subject: [PATCH 5/6] Use constants in test_switch.py --- tests/components/nice_go/test_switch.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/components/nice_go/test_switch.py b/tests/components/nice_go/test_switch.py index f9432010cd4b1a..89905cefbcc2a5 100644 --- a/tests/components/nice_go/test_switch.py +++ b/tests/components/nice_go/test_switch.py @@ -2,6 +2,12 @@ from unittest.mock import AsyncMock +from homeassistant.components.switch import ( + DOMAIN as SWITCH_DOMAIN, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.const import Platform from homeassistant.core import HomeAssistant from . import setup_integration @@ -13,10 +19,10 @@ async def test_turn_on( hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry ) -> None: """Test turn on switch.""" - await setup_integration(hass, mock_config_entry, ["switch"]) + await setup_integration(hass, mock_config_entry, [Platform.SWITCH]) await hass.services.async_call( - "switch", - "turn_on", + SWITCH_DOMAIN, + SERVICE_TURN_ON, {"entity_id": "switch.test_garage_1_vacation_mode"}, blocking=True, ) @@ -27,10 +33,10 @@ async def test_turn_off( hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry ) -> None: """Test turn off switch.""" - await setup_integration(hass, mock_config_entry, ["switch"]) + await setup_integration(hass, mock_config_entry, [Platform.SWITCH]) await hass.services.async_call( - "switch", - "turn_off", + SWITCH_DOMAIN, + SERVICE_TURN_OFF, {"entity_id": "switch.test_garage_2_vacation_mode"}, blocking=True, ) From 877606ecd329b0ae775697178b6eb1b7b4db8e95 Mon Sep 17 00:00:00 2001 From: IceBotYT <34712694+IceBotYT@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:18:00 +0000 Subject: [PATCH 6/6] Use ATTR_ENTITY_ID --- tests/components/nice_go/test_switch.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/components/nice_go/test_switch.py b/tests/components/nice_go/test_switch.py index 89905cefbcc2a5..f34cba495c92cc 100644 --- a/tests/components/nice_go/test_switch.py +++ b/tests/components/nice_go/test_switch.py @@ -7,7 +7,7 @@ SERVICE_TURN_OFF, SERVICE_TURN_ON, ) -from homeassistant.const import Platform +from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import HomeAssistant from . import setup_integration @@ -23,7 +23,7 @@ async def test_turn_on( await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, - {"entity_id": "switch.test_garage_1_vacation_mode"}, + {ATTR_ENTITY_ID: "switch.test_garage_1_vacation_mode"}, blocking=True, ) mock_nice_go.vacation_mode_on.assert_called_once_with("1") @@ -37,7 +37,7 @@ async def test_turn_off( await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_OFF, - {"entity_id": "switch.test_garage_2_vacation_mode"}, + {ATTR_ENTITY_ID: "switch.test_garage_2_vacation_mode"}, blocking=True, ) mock_nice_go.vacation_mode_off.assert_called_once_with("2")