mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Add entity service - Set Full AC state to Sensibo (#80820)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
d4a5393f7b
commit
57b2bb4889
@ -7,12 +7,15 @@ from typing import TYPE_CHECKING, Any
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_FAN_MODE,
|
||||
ATTR_SWING_MODE,
|
||||
ClimateEntity,
|
||||
ClimateEntityFeature,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
ATTR_MODE,
|
||||
ATTR_STATE,
|
||||
ATTR_TEMPERATURE,
|
||||
PRECISION_TENTHS,
|
||||
@ -34,12 +37,16 @@ SERVICE_ENABLE_TIMER = "enable_timer"
|
||||
ATTR_MINUTES = "minutes"
|
||||
SERVICE_ENABLE_PURE_BOOST = "enable_pure_boost"
|
||||
SERVICE_DISABLE_PURE_BOOST = "disable_pure_boost"
|
||||
SERVICE_FULL_STATE = "full_state"
|
||||
|
||||
ATTR_AC_INTEGRATION = "ac_integration"
|
||||
ATTR_GEO_INTEGRATION = "geo_integration"
|
||||
ATTR_INDOOR_INTEGRATION = "indoor_integration"
|
||||
ATTR_OUTDOOR_INTEGRATION = "outdoor_integration"
|
||||
ATTR_SENSITIVITY = "sensitivity"
|
||||
ATTR_TARGET_TEMPERATURE = "target_temperature"
|
||||
ATTR_HORIZONTAL_SWING_MODE = "horizontal_swing_mode"
|
||||
ATTR_LIGHT = "light"
|
||||
BOOST_INCLUSIVE = "boost_inclusive"
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
@ -118,6 +125,20 @@ async def async_setup_entry(
|
||||
},
|
||||
"async_enable_pure_boost",
|
||||
)
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_FULL_STATE,
|
||||
{
|
||||
vol.Required(ATTR_MODE): vol.In(
|
||||
["cool", "heat", "fan", "auto", "dry", "off"]
|
||||
),
|
||||
vol.Optional(ATTR_TARGET_TEMPERATURE): int,
|
||||
vol.Optional(ATTR_FAN_MODE): str,
|
||||
vol.Optional(ATTR_SWING_MODE): str,
|
||||
vol.Optional(ATTR_HORIZONTAL_SWING_MODE): str,
|
||||
vol.Optional(ATTR_LIGHT): vol.In(["on", "off"]),
|
||||
},
|
||||
"async_full_ac_state",
|
||||
)
|
||||
|
||||
|
||||
class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
|
||||
@ -335,6 +356,37 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
|
||||
assumed_state=True,
|
||||
)
|
||||
|
||||
async def async_full_ac_state(
|
||||
self,
|
||||
mode: str,
|
||||
target_temperature: int | None = None,
|
||||
fan_mode: str | None = None,
|
||||
swing_mode: str | None = None,
|
||||
horizontal_swing_mode: str | None = None,
|
||||
light: str | None = None,
|
||||
) -> None:
|
||||
"""Set full AC state."""
|
||||
new_ac_state = self.device_data.ac_states
|
||||
new_ac_state.pop("timestamp")
|
||||
new_ac_state["on"] = False
|
||||
if mode != "off":
|
||||
new_ac_state["on"] = True
|
||||
new_ac_state["mode"] = mode
|
||||
if target_temperature:
|
||||
new_ac_state["targetTemperature"] = target_temperature
|
||||
if fan_mode:
|
||||
new_ac_state["fanLevel"] = fan_mode
|
||||
if swing_mode:
|
||||
new_ac_state["swing"] = swing_mode
|
||||
if horizontal_swing_mode:
|
||||
new_ac_state["horizontalSwing"] = horizontal_swing_mode
|
||||
if light:
|
||||
new_ac_state["light"] = light
|
||||
|
||||
await self.api_call_custom_service_full_ac_state(
|
||||
key="hvac_mode", value=mode, data=new_ac_state
|
||||
)
|
||||
|
||||
async def async_enable_timer(self, minutes: int) -> None:
|
||||
"""Enable the timer."""
|
||||
new_state = bool(self.device_data.ac_states["on"] is False)
|
||||
@ -419,3 +471,14 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
|
||||
result = {}
|
||||
result = await self._client.async_set_pureboost(self._device_id, data)
|
||||
return bool(result.get("status") == "success")
|
||||
|
||||
@async_handle_api_call
|
||||
async def api_call_custom_service_full_ac_state(
|
||||
self,
|
||||
key: str,
|
||||
value: Any,
|
||||
data: dict,
|
||||
) -> bool:
|
||||
"""Make service call to api."""
|
||||
result = await self._client.async_set_ac_states(self._device_id, data)
|
||||
return bool(result.get("result", {}).get("status") == "Success")
|
||||
|
@ -80,3 +80,69 @@ enable_pure_boost:
|
||||
options:
|
||||
- "Normal"
|
||||
- "Sensitive"
|
||||
full_state:
|
||||
name: Set full state
|
||||
description: Set full state for Sensibo device
|
||||
target:
|
||||
entity:
|
||||
integration: sensibo
|
||||
domain: climate
|
||||
fields:
|
||||
mode:
|
||||
name: HVAC mode
|
||||
description: HVAC mode to set
|
||||
required: true
|
||||
example: "heat"
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- "cool"
|
||||
- "heat"
|
||||
- "fan"
|
||||
- "auto"
|
||||
- "dry"
|
||||
- "off"
|
||||
target_temperature:
|
||||
name: Target Temperature
|
||||
description: Optionally set target temperature
|
||||
required: false
|
||||
example: 23
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
step: 1
|
||||
mode: box
|
||||
fan_mode:
|
||||
name: Fan mode
|
||||
description: Optionally set fan mode
|
||||
required: false
|
||||
example: "low"
|
||||
selector:
|
||||
text:
|
||||
type: text
|
||||
swing_mode:
|
||||
name: swing mode
|
||||
description: Optionally set swing mode
|
||||
required: false
|
||||
example: "fixedBottom"
|
||||
selector:
|
||||
text:
|
||||
type: text
|
||||
horizontal_swing_mode:
|
||||
name: Horizontal swing mode
|
||||
description: Optionally set horizontal swing mode
|
||||
required: false
|
||||
example: "fixedLeft"
|
||||
selector:
|
||||
text:
|
||||
type: text
|
||||
light:
|
||||
name: Light
|
||||
description: Set light on or off
|
||||
required: false
|
||||
example: "on"
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- "on"
|
||||
- "off"
|
||||
|
@ -23,19 +23,24 @@ from homeassistant.components.climate import (
|
||||
from homeassistant.components.sensibo.climate import (
|
||||
ATTR_AC_INTEGRATION,
|
||||
ATTR_GEO_INTEGRATION,
|
||||
ATTR_HORIZONTAL_SWING_MODE,
|
||||
ATTR_INDOOR_INTEGRATION,
|
||||
ATTR_LIGHT,
|
||||
ATTR_MINUTES,
|
||||
ATTR_OUTDOOR_INTEGRATION,
|
||||
ATTR_SENSITIVITY,
|
||||
ATTR_TARGET_TEMPERATURE,
|
||||
SERVICE_ASSUME_STATE,
|
||||
SERVICE_ENABLE_PURE_BOOST,
|
||||
SERVICE_ENABLE_TIMER,
|
||||
SERVICE_FULL_STATE,
|
||||
_find_valid_target_temp,
|
||||
)
|
||||
from homeassistant.components.sensibo.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_MODE,
|
||||
ATTR_STATE,
|
||||
ATTR_TEMPERATURE,
|
||||
SERVICE_TURN_OFF,
|
||||
@ -916,3 +921,91 @@ async def test_climate_pure_boost(
|
||||
assert state2.state == "on"
|
||||
assert state3.state == "on"
|
||||
assert state4.state == "s"
|
||||
|
||||
|
||||
async def test_climate_full_ac_state(
|
||||
hass: HomeAssistant,
|
||||
entity_registry_enabled_by_default: AsyncMock,
|
||||
load_int: ConfigEntry,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
get_data: SensiboData,
|
||||
) -> None:
|
||||
"""Test the Sensibo climate Full AC state service."""
|
||||
|
||||
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()
|
||||
|
||||
state_climate = hass.states.get("climate.hallway")
|
||||
assert state_climate.state == "heat"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
|
||||
), patch(
|
||||
"homeassistant.components.sensibo.util.SensiboClient.async_set_ac_states",
|
||||
):
|
||||
with pytest.raises(MultipleInvalid):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_FULL_STATE,
|
||||
{
|
||||
ATTR_ENTITY_ID: state_climate.entity_id,
|
||||
ATTR_TARGET_TEMPERATURE: 22,
|
||||
},
|
||||
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_ac_states",
|
||||
return_value={"result": {"status": "Success"}},
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_FULL_STATE,
|
||||
{
|
||||
ATTR_ENTITY_ID: state_climate.entity_id,
|
||||
ATTR_MODE: "cool",
|
||||
ATTR_TARGET_TEMPERATURE: 22,
|
||||
ATTR_FAN_MODE: "high",
|
||||
ATTR_SWING_MODE: "stopped",
|
||||
ATTR_HORIZONTAL_SWING_MODE: "stopped",
|
||||
ATTR_LIGHT: "on",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
monkeypatch.setattr(get_data.parsed["ABC999111"], "hvac_mode", "cool")
|
||||
monkeypatch.setattr(get_data.parsed["ABC999111"], "device_on", True)
|
||||
monkeypatch.setattr(get_data.parsed["ABC999111"], "target_temp", 22)
|
||||
monkeypatch.setattr(get_data.parsed["ABC999111"], "fan_mode", "high")
|
||||
monkeypatch.setattr(get_data.parsed["ABC999111"], "swing_mode", "stopped")
|
||||
monkeypatch.setattr(
|
||||
get_data.parsed["ABC999111"], "horizontal_swing_mode", "stopped"
|
||||
)
|
||||
monkeypatch.setattr(get_data.parsed["ABC999111"], "light_mode", "on")
|
||||
|
||||
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()
|
||||
|
||||
state = hass.states.get("climate.hallway")
|
||||
|
||||
assert state.state == "cool"
|
||||
assert state.attributes["temperature"] == 22
|
||||
|
Loading…
x
Reference in New Issue
Block a user