mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add get device capabilities action call for Sensibo (#134596)
* Add get device capabilities action call for Sensibo * Tests * Mod * Fix services --------- Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
acd95975e4
commit
eafbf1d1fd
@ -9,6 +9,7 @@ import voluptuous as vol
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_FAN_MODE,
|
||||
ATTR_HVAC_MODE,
|
||||
ATTR_SWING_MODE,
|
||||
ClimateEntity,
|
||||
ClimateEntityFeature,
|
||||
@ -21,8 +22,8 @@ from homeassistant.const import (
|
||||
PRECISION_TENTHS,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.core import HomeAssistant, SupportsResponse
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.helpers import config_validation as cv, entity_platform
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||
@ -39,6 +40,7 @@ SERVICE_ENABLE_PURE_BOOST = "enable_pure_boost"
|
||||
SERVICE_DISABLE_PURE_BOOST = "disable_pure_boost"
|
||||
SERVICE_FULL_STATE = "full_state"
|
||||
SERVICE_ENABLE_CLIMATE_REACT = "enable_climate_react"
|
||||
SERVICE_GET_DEVICE_CAPABILITIES = "get_device_capabilities"
|
||||
ATTR_HIGH_TEMPERATURE_THRESHOLD = "high_temperature_threshold"
|
||||
ATTR_HIGH_TEMPERATURE_STATE = "high_temperature_state"
|
||||
ATTR_LOW_TEMPERATURE_THRESHOLD = "low_temperature_threshold"
|
||||
@ -172,7 +174,6 @@ async def async_setup_entry(
|
||||
},
|
||||
"async_full_ac_state",
|
||||
)
|
||||
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_ENABLE_CLIMATE_REACT,
|
||||
{
|
||||
@ -186,6 +187,12 @@ async def async_setup_entry(
|
||||
},
|
||||
"async_enable_climate_react",
|
||||
)
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_GET_DEVICE_CAPABILITIES,
|
||||
{vol.Required(ATTR_HVAC_MODE): vol.Coerce(HVACMode)},
|
||||
"async_get_device_capabilities",
|
||||
supports_response=SupportsResponse.ONLY,
|
||||
)
|
||||
|
||||
|
||||
class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
|
||||
@ -390,6 +397,26 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
|
||||
assumed_state=False,
|
||||
)
|
||||
|
||||
async def async_get_device_capabilities(
|
||||
self, hvac_mode: HVACMode
|
||||
) -> dict[str, Any]:
|
||||
"""Get capabilities from device."""
|
||||
active_features = self.device_data.active_features
|
||||
mode_capabilities: dict[str, Any] | None = self.device_data.full_capabilities[
|
||||
"modes"
|
||||
].get(hvac_mode.value)
|
||||
if not mode_capabilities:
|
||||
raise ServiceValidationError(
|
||||
translation_domain=DOMAIN, translation_key="mode_not_exist"
|
||||
)
|
||||
remote_capabilities: dict[str, Any] = {}
|
||||
for active_feature in active_features:
|
||||
if active_feature in mode_capabilities:
|
||||
remote_capabilities[active_feature.lower()] = mode_capabilities[
|
||||
active_feature
|
||||
]
|
||||
return remote_capabilities
|
||||
|
||||
async def async_assume_state(self, state: str) -> None:
|
||||
"""Sync state with api."""
|
||||
await self.async_send_api_call(
|
||||
|
@ -59,6 +59,9 @@
|
||||
},
|
||||
"enable_climate_react": {
|
||||
"service": "mdi:wizard-hat"
|
||||
},
|
||||
"get_device_capabilities": {
|
||||
"service": "mdi:shape-outline"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -159,3 +159,21 @@ enable_climate_react:
|
||||
- "feelslike"
|
||||
- "humidity"
|
||||
translation_key: smart_type
|
||||
get_device_capabilities:
|
||||
target:
|
||||
entity:
|
||||
integration: sensibo
|
||||
domain: climate
|
||||
fields:
|
||||
hvac_mode:
|
||||
required: true
|
||||
example: "heat"
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- "auto"
|
||||
- "cool"
|
||||
- "dry"
|
||||
- "fan"
|
||||
- "heat"
|
||||
translation_key: hvac_mode
|
||||
|
@ -494,6 +494,16 @@
|
||||
"description": "Choose between temperature/feels like/humidity."
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_device_capabilities": {
|
||||
"name": "Get device mode capabilities",
|
||||
"description": "Retrieve the device capabilities for a specific device according to api requirements.",
|
||||
"fields": {
|
||||
"hvac_mode": {
|
||||
"name": "[%key:component::climate::services::set_hvac_mode::fields::hvac_mode::name%]",
|
||||
"description": "[%key:component::climate::services::set_hvac_mode::fields::hvac_mode::description%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
@ -561,6 +571,9 @@
|
||||
},
|
||||
"no_data": {
|
||||
"message": "[%key:component::sensibo::config::error::no_devices%]"
|
||||
},
|
||||
"mode_not_exist": {
|
||||
"message": "The entity does not support the chosen mode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,3 +227,23 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_climate_get_device_capabilities
|
||||
dict({
|
||||
'climate.hallway': dict({
|
||||
'horizontalswing': list([
|
||||
'stopped',
|
||||
'fixedLeft',
|
||||
'fixedCenterLeft',
|
||||
]),
|
||||
'light': list([
|
||||
'on',
|
||||
'off',
|
||||
]),
|
||||
'swing': list([
|
||||
'stopped',
|
||||
'fixedTop',
|
||||
'fixedMiddleTop',
|
||||
]),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
|
@ -43,6 +43,7 @@ from homeassistant.components.sensibo.climate import (
|
||||
SERVICE_ENABLE_PURE_BOOST,
|
||||
SERVICE_ENABLE_TIMER,
|
||||
SERVICE_FULL_STATE,
|
||||
SERVICE_GET_DEVICE_CAPABILITIES,
|
||||
_find_valid_target_temp,
|
||||
)
|
||||
from homeassistant.components.sensibo.const import DOMAIN
|
||||
@ -1187,3 +1188,33 @@ async def test_climate_fan_mode_and_swing_mode_not_supported(
|
||||
state = hass.states.get("climate.hallway")
|
||||
assert state.attributes["fan_mode"] == "high"
|
||||
assert state.attributes["swing_mode"] == "stopped"
|
||||
|
||||
|
||||
async def test_climate_get_device_capabilities(
|
||||
hass: HomeAssistant,
|
||||
load_int: ConfigEntry,
|
||||
mock_client: MagicMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the Sensibo climate Get device capabilitites service."""
|
||||
|
||||
response = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_GET_DEVICE_CAPABILITIES,
|
||||
{ATTR_ENTITY_ID: "climate.hallway", ATTR_HVAC_MODE: "heat"},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
assert response == snapshot
|
||||
|
||||
with pytest.raises(
|
||||
ServiceValidationError, match="The entity does not support the chosen mode"
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_GET_DEVICE_CAPABILITIES,
|
||||
{ATTR_ENTITY_ID: "climate.hallway", ATTR_HVAC_MODE: "heat_cool"},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user