diff --git a/homeassistant/components/sensibo/binary_sensor.py b/homeassistant/components/sensibo/binary_sensor.py index 72003e0a4189..503717c61e42 100644 --- a/homeassistant/components/sensibo/binary_sensor.py +++ b/homeassistant/components/sensibo/binary_sensor.py @@ -1,9 +1,9 @@ """Binary Sensor platform for Sensibo integration.""" from __future__ import annotations -from collections.abc import Callable, Mapping +from collections.abc import Callable from dataclasses import dataclass -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from pysensibo.model import MotionSensor, SensiboDevice @@ -36,7 +36,6 @@ class DeviceBaseEntityDescriptionMixin: """Mixin for required Sensibo base description keys.""" value_fn: Callable[[SensiboDevice], bool | None] - extra_fn: Callable[[SensiboDevice], dict[str, str | bool | None] | None] | None @dataclass @@ -85,18 +84,6 @@ class SensiboDeviceBinarySensorEntityDescription( name="Room Occupied", icon="mdi:motion-sensor", value_fn=lambda data: data.room_occupied, - extra_fn=None, - ), -) - -DEVICE_SENSOR_TYPES: tuple[SensiboDeviceBinarySensorEntityDescription, ...] = ( - SensiboDeviceBinarySensorEntityDescription( - key="timer_on", - device_class=BinarySensorDeviceClass.RUNNING, - name="Timer Running", - icon="mdi:timer", - value_fn=lambda data: data.timer_on, - extra_fn=lambda data: {"id": data.timer_id, "turn_on": data.timer_state_on}, ), ) @@ -107,7 +94,6 @@ class SensiboDeviceBinarySensorEntityDescription( name="Pure Boost Enabled", icon="mdi:wind-power-outline", value_fn=lambda data: data.pure_boost_enabled, - extra_fn=None, ), SensiboDeviceBinarySensorEntityDescription( key="pure_ac_integration", @@ -116,7 +102,6 @@ class SensiboDeviceBinarySensorEntityDescription( name="Pure Boost linked with AC", icon="mdi:connection", value_fn=lambda data: data.pure_ac_integration, - extra_fn=None, ), SensiboDeviceBinarySensorEntityDescription( key="pure_geo_integration", @@ -125,7 +110,6 @@ class SensiboDeviceBinarySensorEntityDescription( name="Pure Boost linked with Presence", icon="mdi:connection", value_fn=lambda data: data.pure_geo_integration, - extra_fn=None, ), SensiboDeviceBinarySensorEntityDescription( key="pure_measure_integration", @@ -134,7 +118,6 @@ class SensiboDeviceBinarySensorEntityDescription( name="Pure Boost linked with Indoor Air Quality", icon="mdi:connection", value_fn=lambda data: data.pure_measure_integration, - extra_fn=None, ), SensiboDeviceBinarySensorEntityDescription( key="pure_prime_integration", @@ -143,7 +126,6 @@ class SensiboDeviceBinarySensorEntityDescription( name="Pure Boost linked with Outdoor Air Quality", icon="mdi:connection", value_fn=lambda data: data.pure_prime_integration, - extra_fn=None, ), ) @@ -172,12 +154,6 @@ async def async_setup_entry( for device_id, device_data in coordinator.data.parsed.items() if device_data.motion_sensors is not None ) - entities.extend( - SensiboDeviceSensor(coordinator, device_id, description) - for description in DEVICE_SENSOR_TYPES - for device_id, device_data in coordinator.data.parsed.items() - if device_data.model != "pure" - ) entities.extend( SensiboDeviceSensor(coordinator, device_id, description) for description in PURE_SENSOR_TYPES @@ -247,10 +223,3 @@ def __init__( def is_on(self) -> bool | None: """Return true if the binary sensor is on.""" return self.entity_description.value_fn(self.device_data) - - @property - def extra_state_attributes(self) -> Mapping[str, Any] | None: - """Return additional attributes.""" - if self.entity_description.extra_fn is not None: - return self.entity_description.extra_fn(self.device_data) - return None diff --git a/homeassistant/components/sensibo/climate.py b/homeassistant/components/sensibo/climate.py index c146ed350f34..6a1084f733c6 100644 --- a/homeassistant/components/sensibo/climate.py +++ b/homeassistant/components/sensibo/climate.py @@ -27,7 +27,7 @@ from .entity import SensiboDeviceBaseEntity SERVICE_ASSUME_STATE = "assume_state" -SERVICE_TIMER = "timer" +SERVICE_ENABLE_TIMER = "enable_timer" ATTR_MINUTES = "minutes" SERVICE_ENABLE_PURE_BOOST = "enable_pure_boost" SERVICE_DISABLE_PURE_BOOST = "disable_pure_boost" @@ -98,12 +98,11 @@ async def async_setup_entry( "async_assume_state", ) platform.async_register_entity_service( - SERVICE_TIMER, + SERVICE_ENABLE_TIMER, { - vol.Required(ATTR_STATE): vol.In(["on", "off"]), - vol.Optional(ATTR_MINUTES): cv.positive_int, + vol.Required(ATTR_MINUTES): cv.positive_int, }, - "async_set_timer", + "async_enable_timer", ) platform.async_register_entity_service( SERVICE_ENABLE_PURE_BOOST, @@ -315,27 +314,18 @@ async def async_assume_state(self, state: str) -> None: await self._async_set_ac_state_property("on", state != HVACMode.OFF, True) await self.coordinator.async_refresh() - async def async_set_timer(self, state: str, minutes: int | None = None) -> None: - """Set or delete timer.""" - if state == "off" and self.device_data.timer_id is None: - raise HomeAssistantError("No timer to delete") - - if state == "on" and minutes is None: - raise ValueError("No value provided for timer") - - if state == "off": - result = await self.async_send_command("del_timer") - else: - new_state = bool(self.device_data.ac_states["on"] is False) - params = { - "minutesFromNow": minutes, - "acState": {**self.device_data.ac_states, "on": new_state}, - } - result = await self.async_send_command("set_timer", params) + async def async_enable_timer(self, minutes: int) -> None: + """Enable the timer.""" + new_state = bool(self.device_data.ac_states["on"] is False) + params = { + "minutesFromNow": minutes, + "acState": {**self.device_data.ac_states, "on": new_state}, + } + result = await self.async_send_command("set_timer", params) if result["status"] == "success": return await self.coordinator.async_request_refresh() - raise HomeAssistantError(f"Could not set timer for device {self.name}") + raise HomeAssistantError(f"Could not enable timer for device {self.name}") async def async_enable_pure_boost( self, diff --git a/homeassistant/components/sensibo/const.py b/homeassistant/components/sensibo/const.py index 5fce3822bb21..736d663b144d 100644 --- a/homeassistant/components/sensibo/const.py +++ b/homeassistant/components/sensibo/const.py @@ -18,6 +18,7 @@ Platform.NUMBER, Platform.SELECT, Platform.SENSOR, + Platform.SWITCH, Platform.UPDATE, ] DEFAULT_NAME = "Sensibo" diff --git a/homeassistant/components/sensibo/services.yaml b/homeassistant/components/sensibo/services.yaml index 67006074f6bf..6eb5c0657893 100644 --- a/homeassistant/components/sensibo/services.yaml +++ b/homeassistant/components/sensibo/services.yaml @@ -16,24 +16,14 @@ assume_state: options: - "on" - "off" -timer: - name: Timer - description: Set or delete timer for device. +enable_timer: + name: Enable Timer + description: Enable the timer with custom time. target: entity: integration: sensibo domain: climate fields: - state: - name: State - description: Timer on or off. - required: true - example: "on" - selector: - select: - options: - - "on" - - "off" minutes: name: Minutes description: Countdown for timer (for timer state on) diff --git a/homeassistant/components/sensibo/switch.py b/homeassistant/components/sensibo/switch.py new file mode 100644 index 000000000000..3b9915d0a89f --- /dev/null +++ b/homeassistant/components/sensibo/switch.py @@ -0,0 +1,146 @@ +"""Switch platform for Sensibo integration.""" +from __future__ import annotations + +from collections.abc import Callable, Mapping +from dataclasses import dataclass +from typing import Any + +from pysensibo.model import SensiboDevice + +from homeassistant.components.switch import ( + SwitchDeviceClass, + SwitchEntity, + SwitchEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .coordinator import SensiboDataUpdateCoordinator +from .entity import SensiboDeviceBaseEntity + +PARALLEL_UPDATES = 0 + + +@dataclass +class DeviceBaseEntityDescriptionMixin: + """Mixin for required Sensibo base description keys.""" + + value_fn: Callable[[SensiboDevice], bool | None] + extra_fn: Callable[[SensiboDevice], dict[str, str | bool | None]] + command_on: str + command_off: str + remote_key: str + + +@dataclass +class SensiboDeviceSwitchEntityDescription( + SwitchEntityDescription, DeviceBaseEntityDescriptionMixin +): + """Describes Sensibo Switch entity.""" + + +DEVICE_SWITCH_TYPES: tuple[SensiboDeviceSwitchEntityDescription, ...] = ( + SensiboDeviceSwitchEntityDescription( + key="timer_on_switch", + device_class=SwitchDeviceClass.SWITCH, + name="Timer", + icon="mdi:timer", + value_fn=lambda data: data.timer_on, + extra_fn=lambda data: {"id": data.timer_id, "turn_on": data.timer_state_on}, + command_on="set_timer", + command_off="del_timer", + remote_key="timer_on", + ), +) + + +def build_params(command: str, device_data: SensiboDevice) -> dict[str, Any] | None: + """Build params for turning on switch.""" + if command == "set_timer": + new_state = bool(device_data.ac_states["on"] is False) + params = { + "minutesFromNow": 60, + "acState": {**device_data.ac_states, "on": new_state}, + } + return params + return None + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Set up Sensibo binary sensor platform.""" + + coordinator: SensiboDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + + entities: list[SensiboDeviceSwitch] = [] + + entities.extend( + SensiboDeviceSwitch(coordinator, device_id, description) + for description in DEVICE_SWITCH_TYPES + for device_id, device_data in coordinator.data.parsed.items() + if device_data.model != "pure" + ) + + async_add_entities(entities) + + +class SensiboDeviceSwitch(SensiboDeviceBaseEntity, SwitchEntity): + """Representation of a Sensibo Device Switch.""" + + entity_description: SensiboDeviceSwitchEntityDescription + + def __init__( + self, + coordinator: SensiboDataUpdateCoordinator, + device_id: str, + entity_description: SensiboDeviceSwitchEntityDescription, + ) -> None: + """Initiate Sensibo Device Switch.""" + super().__init__( + coordinator, + device_id, + ) + self.entity_description = entity_description + self._attr_unique_id = f"{device_id}-{entity_description.key}" + self._attr_name = f"{self.device_data.name} {entity_description.name}" + + @property + def is_on(self) -> bool | None: + """Return True if entity is on.""" + return self.entity_description.value_fn(self.device_data) + + async def async_turn_on(self, **kwargs: Any) -> None: + """Turn the entity on.""" + params = build_params(self.entity_description.command_on, self.device_data) + result = await self.async_send_command( + self.entity_description.command_on, params + ) + + if result["status"] == "success": + setattr(self.device_data, self.entity_description.remote_key, True) + self.async_write_ha_state() + return await self.coordinator.async_request_refresh() + raise HomeAssistantError( + f"Could not execute {self.entity_description.command_on} for device {self.name}" + ) + + async def async_turn_off(self, **kwargs: Any) -> None: + """Turn the entity off.""" + result = await self.async_send_command(self.entity_description.command_off) + + if result["status"] == "success": + setattr(self.device_data, self.entity_description.remote_key, False) + self.async_write_ha_state() + return await self.coordinator.async_request_refresh() + raise HomeAssistantError( + f"Could not execute {self.entity_description.command_off} for device {self.name}" + ) + + @property + def extra_state_attributes(self) -> Mapping[str, Any]: + """Return additional attributes.""" + return self.entity_description.extra_fn(self.device_data) diff --git a/tests/components/sensibo/test_climate.py b/tests/components/sensibo/test_climate.py index 30356f2b00dd..ea7f6eb16fe1 100644 --- a/tests/components/sensibo/test_climate.py +++ b/tests/components/sensibo/test_climate.py @@ -30,7 +30,7 @@ SERVICE_ASSUME_STATE, SERVICE_DISABLE_PURE_BOOST, SERVICE_ENABLE_PURE_BOOST, - SERVICE_TIMER, + SERVICE_ENABLE_TIMER, _find_valid_target_temp, ) from homeassistant.components.sensibo.const import DOMAIN @@ -706,146 +706,58 @@ async def test_climate_set_timer( ) await hass.async_block_till_done() - state1 = hass.states.get("climate.hallway") + state_climate = hass.states.get("climate.hallway") assert hass.states.get("sensor.hallway_timer_end_time").state == STATE_UNKNOWN - assert hass.states.get("binary_sensor.hallway_timer_running").state == "off" with patch( "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", return_value=get_data, ), patch( "homeassistant.components.sensibo.util.SensiboClient.async_set_timer", - return_value={"status": "success", "result": {"id": "SzTGE4oZ4D"}}, + return_value={"status": "failure"}, ): - await hass.services.async_call( - DOMAIN, - SERVICE_TIMER, - { - ATTR_ENTITY_ID: state1.entity_id, - ATTR_STATE: "on", - ATTR_MINUTES: 30, - }, - blocking=True, - ) + with pytest.raises(MultipleInvalid): + await hass.services.async_call( + DOMAIN, + SERVICE_ENABLE_TIMER, + { + ATTR_ENTITY_ID: state_climate.entity_id, + }, + blocking=True, + ) await hass.async_block_till_done() - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_on", True) - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_id", "SzTGE4oZ4D") - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_state_on", False) - monkeypatch.setattr( - get_data.parsed["ABC999111"], - "timer_time", - datetime(2022, 6, 6, 12, 00, 00, tzinfo=dt.UTC), - ) - - with patch( - "homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data", - return_value=get_data, - ): - async_fire_time_changed( - hass, - dt.utcnow() + timedelta(minutes=5), - ) - await hass.async_block_till_done() - - assert ( - hass.states.get("sensor.hallway_timer_end_time").state - == "2022-06-06T12:00:00+00:00" - ) - assert hass.states.get("binary_sensor.hallway_timer_running").state == "on" - assert hass.states.get("binary_sensor.hallway_timer_running").attributes == { - "device_class": "running", - "friendly_name": "Hallway Timer Running", - "icon": "mdi:timer", - "id": "SzTGE4oZ4D", - "turn_on": False, - } - with patch( "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", return_value=get_data, ), patch( - "homeassistant.components.sensibo.util.SensiboClient.async_del_timer", - return_value={"status": "success"}, + "homeassistant.components.sensibo.util.SensiboClient.async_set_timer", + return_value={"status": "failure"}, ): - await hass.services.async_call( - DOMAIN, - SERVICE_TIMER, - { - ATTR_ENTITY_ID: state1.entity_id, - ATTR_STATE: "off", - }, - blocking=True, - ) + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + DOMAIN, + SERVICE_ENABLE_TIMER, + { + ATTR_ENTITY_ID: state_climate.entity_id, + ATTR_MINUTES: 30, + }, + blocking=True, + ) await hass.async_block_till_done() - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_on", False) - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_id", None) - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_state_on", None) - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_time", None) - - with patch( - "homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data", - return_value=get_data, - ): - async_fire_time_changed( - hass, - dt.utcnow() + timedelta(minutes=5), - ) - await hass.async_block_till_done() - - assert hass.states.get("sensor.hallway_timer_end_time").state == STATE_UNKNOWN - assert hass.states.get("binary_sensor.hallway_timer_running").state == "off" - - -async def test_climate_set_timer_failures( - hass: HomeAssistant, - entity_registry_enabled_by_default: AsyncMock, - load_int: ConfigEntry, - monkeypatch: pytest.MonkeyPatch, - get_data: SensiboData, -) -> None: - """Test the Sensibo climate Set Timer service failures.""" - - with patch( - "homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data", - return_value=get_data, - ): - async_fire_time_changed( - hass, - dt.utcnow() + timedelta(minutes=5), - ) - await hass.async_block_till_done() - - state1 = hass.states.get("climate.hallway") - assert hass.states.get("sensor.hallway_timer_end_time").state == STATE_UNKNOWN - assert hass.states.get("binary_sensor.hallway_timer_running").state == "off" - - with pytest.raises(ValueError): - await hass.services.async_call( - DOMAIN, - SERVICE_TIMER, - { - ATTR_ENTITY_ID: state1.entity_id, - ATTR_STATE: "on", - }, - blocking=True, - ) - await hass.async_block_till_done() - with patch( "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", return_value=get_data, ), patch( "homeassistant.components.sensibo.util.SensiboClient.async_set_timer", - return_value={"status": "success", "result": {"id": ""}}, + return_value={"status": "success", "result": {"id": "SzTGE4oZ4D"}}, ): await hass.services.async_call( DOMAIN, - SERVICE_TIMER, + SERVICE_ENABLE_TIMER, { - ATTR_ENTITY_ID: state1.entity_id, - ATTR_STATE: "on", + ATTR_ENTITY_ID: state_climate.entity_id, ATTR_MINUTES: 30, }, blocking=True, @@ -853,7 +765,7 @@ async def test_climate_set_timer_failures( await hass.async_block_till_done() monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_on", True) - monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_id", None) + monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_id", "SzTGE4oZ4D") monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_state_on", False) monkeypatch.setattr( get_data.parsed["ABC999111"], @@ -871,47 +783,10 @@ async def test_climate_set_timer_failures( ) await hass.async_block_till_done() - with pytest.raises(HomeAssistantError): - await hass.services.async_call( - DOMAIN, - SERVICE_TIMER, - { - ATTR_ENTITY_ID: state1.entity_id, - ATTR_STATE: "off", - }, - blocking=True, - ) - await hass.async_block_till_done() - - with patch( - "homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data", - return_value=get_data, - ): - async_fire_time_changed( - hass, - dt.utcnow() + timedelta(minutes=5), - ) - await hass.async_block_till_done() - - with patch( - "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", - return_value=get_data, - ), patch( - "homeassistant.components.sensibo.util.SensiboClient.async_set_timer", - return_value={"status": "failure"}, - ): - with pytest.raises(HomeAssistantError): - await hass.services.async_call( - DOMAIN, - SERVICE_TIMER, - { - ATTR_ENTITY_ID: state1.entity_id, - ATTR_STATE: "on", - ATTR_MINUTES: 30, - }, - blocking=True, - ) - await hass.async_block_till_done() + assert ( + hass.states.get("sensor.hallway_timer_end_time").state + == "2022-06-06T12:00:00+00:00" + ) async def test_climate_pure_boost( diff --git a/tests/components/sensibo/test_switch.py b/tests/components/sensibo/test_switch.py new file mode 100644 index 000000000000..49efca4103eb --- /dev/null +++ b/tests/components/sensibo/test_switch.py @@ -0,0 +1,165 @@ +"""The test for the sensibo switch platform.""" +from __future__ import annotations + +from datetime import timedelta +from unittest.mock import patch + +from pysensibo.model import SensiboData +import pytest +from pytest import MonkeyPatch + +from homeassistant.components.sensibo.switch import build_params +from homeassistant.components.switch.const import DOMAIN as SWITCH_DOMAIN +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ( + ATTR_ENTITY_ID, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, + STATE_OFF, + STATE_ON, +) +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError +from homeassistant.util import dt + +from tests.common import async_fire_time_changed + + +async def test_switch( + hass: HomeAssistant, + load_int: ConfigEntry, + monkeypatch: MonkeyPatch, + get_data: SensiboData, +) -> None: + """Test the Sensibo switch.""" + + state1 = hass.states.get("switch.hallway_timer") + assert state1.state == STATE_OFF + assert state1.attributes["id"] is None + assert state1.attributes["turn_on"] is None + + with patch( + "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", + return_value=get_data, + ), patch( + "homeassistant.components.sensibo.util.SensiboClient.async_set_timer", + return_value={"status": "success", "result": {"id": "SzTGE4oZ4D"}}, + ): + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: state1.entity_id, + }, + blocking=True, + ) + await hass.async_block_till_done() + + monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_on", True) + monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_id", "SzTGE4oZ4D") + monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_state_on", False) + with patch( + "homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data", + return_value=get_data, + ): + async_fire_time_changed( + hass, + dt.utcnow() + timedelta(minutes=5), + ) + await hass.async_block_till_done() + state1 = hass.states.get("switch.hallway_timer") + assert state1.state == STATE_ON + assert state1.attributes["id"] == "SzTGE4oZ4D" + assert state1.attributes["turn_on"] is False + + with patch( + "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", + return_value=get_data, + ), patch( + "homeassistant.components.sensibo.util.SensiboClient.async_del_timer", + return_value={"status": "success", "result": {"id": "SzTGE4oZ4D"}}, + ): + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + { + ATTR_ENTITY_ID: state1.entity_id, + }, + blocking=True, + ) + await hass.async_block_till_done() + + monkeypatch.setattr(get_data.parsed["ABC999111"], "timer_on", False) + + with patch( + "homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data", + return_value=get_data, + ): + async_fire_time_changed( + hass, + dt.utcnow() + timedelta(minutes=5), + ) + await hass.async_block_till_done() + + state1 = hass.states.get("switch.hallway_timer") + assert state1.state == STATE_OFF + + +async def test_switch_command_failure( + hass: HomeAssistant, + load_int: ConfigEntry, + monkeypatch: MonkeyPatch, + get_data: SensiboData, +) -> None: + """Test the Sensibo switch fails commands.""" + + state1 = hass.states.get("switch.hallway_timer") + + with patch( + "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", + return_value=get_data, + ), patch( + "homeassistant.components.sensibo.util.SensiboClient.async_set_timer", + return_value={"status": "failure"}, + ): + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: state1.entity_id, + }, + blocking=True, + ) + + with patch( + "homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data", + return_value=get_data, + ), patch( + "homeassistant.components.sensibo.util.SensiboClient.async_del_timer", + return_value={"status": "failure"}, + ): + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + { + ATTR_ENTITY_ID: state1.entity_id, + }, + blocking=True, + ) + + +async def test_build_params( + hass: HomeAssistant, + load_int: ConfigEntry, + monkeypatch: MonkeyPatch, + get_data: SensiboData, +) -> None: + """Test the build params method.""" + + assert build_params("set_timer", get_data.parsed["ABC999111"]) == { + "minutesFromNow": 60, + "acState": {**get_data.parsed["ABC999111"].ac_states, "on": False}, + } + assert build_params("incorrect_command", get_data.parsed["ABC999111"]) is None