Sensibo Add Pure Boost Service (#73114)

* Pure Boost Service

* Fix tests

* Fix mypy

* One service to two services

* Minor fix test

* Fix issues
This commit is contained in:
G Johansson 2022-06-18 22:15:44 +02:00 committed by GitHub
parent 046d7d2a23
commit d5df2b2ee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 277 additions and 0 deletions

View File

@ -29,6 +29,16 @@ from .entity import SensiboDeviceBaseEntity
SERVICE_ASSUME_STATE = "assume_state"
SERVICE_TIMER = "timer"
ATTR_MINUTES = "minutes"
SERVICE_ENABLE_PURE_BOOST = "enable_pure_boost"
SERVICE_DISABLE_PURE_BOOST = "disable_pure_boost"
ATTR_AC_INTEGRATION = "ac_integration"
ATTR_GEO_INTEGRATION = "geo_integration"
ATTR_INDOOR_INTEGRATION = "indoor_integration"
ATTR_OUTDOOR_INTEGRATION = "outdoor_integration"
ATTR_SENSITIVITY = "sensitivity"
BOOST_INCLUSIVE = "boost_inclusive"
PARALLEL_UPDATES = 0
FIELD_TO_FLAG = {
@ -95,6 +105,24 @@ async def async_setup_entry(
},
"async_set_timer",
)
platform.async_register_entity_service(
SERVICE_ENABLE_PURE_BOOST,
{
vol.Inclusive(ATTR_AC_INTEGRATION, "settings"): bool,
vol.Inclusive(ATTR_GEO_INTEGRATION, "settings"): bool,
vol.Inclusive(ATTR_INDOOR_INTEGRATION, "settings"): bool,
vol.Inclusive(ATTR_OUTDOOR_INTEGRATION, "settings"): bool,
vol.Inclusive(ATTR_SENSITIVITY, "settings"): vol.In(
["Normal", "Sensitive"]
),
},
"async_enable_pure_boost",
)
platform.async_register_entity_service(
SERVICE_DISABLE_PURE_BOOST,
{},
"async_disable_pure_boost",
)
class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
@ -308,3 +336,36 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
if result["status"] == "success":
return await self.coordinator.async_request_refresh()
raise HomeAssistantError(f"Could not set timer for device {self.name}")
async def async_enable_pure_boost(
self,
ac_integration: bool | None = None,
geo_integration: bool | None = None,
indoor_integration: bool | None = None,
outdoor_integration: bool | None = None,
sensitivity: str | None = None,
) -> None:
"""Enable Pure Boost Configuration."""
params: dict[str, str | bool] = {
"enabled": True,
}
if sensitivity is not None:
params["sensitivity"] = sensitivity[0]
if indoor_integration is not None:
params["measurementsIntegration"] = indoor_integration
if ac_integration is not None:
params["acIntegration"] = ac_integration
if geo_integration is not None:
params["geoIntegration"] = geo_integration
if outdoor_integration is not None:
params["primeIntegration"] = outdoor_integration
await self.async_send_command("set_pure_boost", params)
await self.coordinator.async_refresh()
async def async_disable_pure_boost(self) -> None:
"""Disable Pure Boost Configuration."""
await self.async_send_command("set_pure_boost", {"enabled": False})
await self.coordinator.async_refresh()

View File

@ -99,6 +99,13 @@ class SensiboDeviceBaseEntity(SensiboBaseEntity):
result = await self._client.async_set_timer(self._device_id, params)
if command == "del_timer":
result = await self._client.async_del_timer(self._device_id)
if command == "set_pure_boost":
if TYPE_CHECKING:
assert params is not None
result = await self._client.async_set_pureboost(
self._device_id,
params,
)
return result

View File

@ -44,3 +44,56 @@ timer:
min: 0
step: 1
mode: box
enable_pure_boost:
name: Enable Pure Boost
description: Enable and configure Pure Boost settings.
target:
entity:
integration: sensibo
domain: climate
fields:
ac_integration:
name: AC Integration
description: Integrate with Air Conditioner.
required: false
example: true
selector:
boolean:
geo_integration:
name: Geo Integration
description: Integrate with Presence.
required: false
example: true
selector:
boolean:
indoor_integration:
name: Indoor Air Quality
description: Integrate with checking indoor air quality.
required: false
example: true
selector:
boolean:
outdoor_integration:
name: Outdoor Air Quality
description: Integrate with checking outdoor air quality.
required: false
example: true
selector:
boolean:
sensitivity:
name: Sensitivity
description: Set the sensitivity for Pure Boost.
required: false
example: "Normal"
selector:
select:
options:
- "Normal"
- "Sensitive"
disable_pure_boost:
name: Disable Pure Boost
description: Disable Pure Boost.
target:
entity:
integration: sensibo
domain: climate

View File

@ -21,8 +21,15 @@ from homeassistant.components.climate.const import (
SERVICE_SET_TEMPERATURE,
)
from homeassistant.components.sensibo.climate import (
ATTR_AC_INTEGRATION,
ATTR_GEO_INTEGRATION,
ATTR_INDOOR_INTEGRATION,
ATTR_MINUTES,
ATTR_OUTDOOR_INTEGRATION,
ATTR_SENSITIVITY,
SERVICE_ASSUME_STATE,
SERVICE_DISABLE_PURE_BOOST,
SERVICE_ENABLE_PURE_BOOST,
SERVICE_TIMER,
_find_valid_target_temp,
)
@ -905,3 +912,152 @@ async def test_climate_set_timer_failures(
blocking=True,
)
await hass.async_block_till_done()
async def test_climate_pure_boost(
hass: HomeAssistant,
entity_registry_enabled_by_default: AsyncMock,
load_int: ConfigEntry,
monkeypatch: pytest.MonkeyPatch,
get_data: SensiboData,
) -> None:
"""Test the Sensibo climate assumed 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.kitchen")
state2 = hass.states.get("binary_sensor.kitchen_pure_boost_enabled")
assert state2.state == "off"
with patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
), patch(
"homeassistant.components.sensibo.util.SensiboClient.async_set_pureboost",
):
with pytest.raises(MultipleInvalid):
await hass.services.async_call(
DOMAIN,
SERVICE_ENABLE_PURE_BOOST,
{
ATTR_ENTITY_ID: state_climate.entity_id,
ATTR_INDOOR_INTEGRATION: True,
ATTR_OUTDOOR_INTEGRATION: True,
ATTR_SENSITIVITY: "Sensitive",
},
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_pureboost",
return_value={
"status": "success",
"result": {
"enabled": True,
"sensitivity": "S",
"measurements_integration": True,
"ac_integration": False,
"geo_integration": False,
"prime_integration": True,
},
},
):
await hass.services.async_call(
DOMAIN,
SERVICE_ENABLE_PURE_BOOST,
{
ATTR_ENTITY_ID: state_climate.entity_id,
ATTR_AC_INTEGRATION: False,
ATTR_GEO_INTEGRATION: False,
ATTR_INDOOR_INTEGRATION: True,
ATTR_OUTDOOR_INTEGRATION: True,
ATTR_SENSITIVITY: "Sensitive",
},
blocking=True,
)
await hass.async_block_till_done()
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_boost_enabled", True)
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_sensitivity", "s")
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_measure_integration", True)
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_prime_integration", True)
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("binary_sensor.kitchen_pure_boost_enabled")
state2 = hass.states.get(
"binary_sensor.kitchen_pure_boost_linked_with_indoor_air_quality"
)
state3 = hass.states.get(
"binary_sensor.kitchen_pure_boost_linked_with_outdoor_air_quality"
)
state4 = hass.states.get("sensor.kitchen_pure_sensitivity")
assert state1.state == "on"
assert state2.state == "on"
assert state3.state == "on"
assert state4.state == "s"
with patch(
"homeassistant.components.sensibo.util.SensiboClient.async_get_devices_data",
return_value=get_data,
), patch(
"homeassistant.components.sensibo.coordinator.SensiboClient.async_set_pureboost",
return_value={
"status": "success",
"result": {
"enabled": False,
"sensitivity": "S",
"measurements_integration": True,
"ac_integration": False,
"geo_integration": False,
"prime_integration": True,
},
},
) as mock_set_pureboost:
await hass.services.async_call(
DOMAIN,
SERVICE_DISABLE_PURE_BOOST,
{
ATTR_ENTITY_ID: state_climate.entity_id,
},
blocking=True,
)
await hass.async_block_till_done()
mock_set_pureboost.assert_called_once()
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_boost_enabled", False)
monkeypatch.setattr(get_data.parsed["AAZZAAZZ"], "pure_sensitivity", "s")
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("binary_sensor.kitchen_pure_boost_enabled")
state4 = hass.states.get("sensor.kitchen_pure_sensitivity")
assert state1.state == "off"
assert state4.state == "s"