mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Add ServiceValidationError to Home Connect (#129309)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
cbfa3bb56d
commit
668626b920
@ -303,3 +303,14 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
|||||||
|
|
||||||
_LOGGER.debug("Migration to version %s successful", config_entry.version)
|
_LOGGER.debug("Migration to version %s successful", config_entry.version)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_dict_from_home_connect_error(err: api.HomeConnectError) -> dict[str, Any]:
|
||||||
|
"""Return a dict from a Home Connect error."""
|
||||||
|
return (
|
||||||
|
err.args[0]
|
||||||
|
if len(err.args) > 0 and isinstance(err.args[0], dict)
|
||||||
|
else {"description": err.args[0]}
|
||||||
|
if len(err.args) > 0 and isinstance(err.args[0], str)
|
||||||
|
else {}
|
||||||
|
)
|
||||||
|
@ -114,6 +114,11 @@ ATTR_STEPSIZE = "stepsize"
|
|||||||
ATTR_UNIT = "unit"
|
ATTR_UNIT = "unit"
|
||||||
ATTR_VALUE = "value"
|
ATTR_VALUE = "value"
|
||||||
|
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_APPLIANCE_NAME = "appliance_name"
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID = "entity_id"
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY = "setting_key"
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_VALUE = "value"
|
||||||
|
|
||||||
OLD_NEW_UNIQUE_ID_SUFFIX_MAP = {
|
OLD_NEW_UNIQUE_ID_SUFFIX_MAP = {
|
||||||
"ChildLock": BSH_CHILD_LOCK_STATE,
|
"ChildLock": BSH_CHILD_LOCK_STATE,
|
||||||
"Operation State": BSH_OPERATION_STATE,
|
"Operation State": BSH_OPERATION_STATE,
|
||||||
|
@ -17,9 +17,11 @@ from homeassistant.components.light import (
|
|||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
import homeassistant.util.color as color_util
|
import homeassistant.util.color as color_util
|
||||||
|
|
||||||
|
from . import get_dict_from_home_connect_error
|
||||||
from .api import ConfigEntryAuth, HomeConnectDevice
|
from .api import ConfigEntryAuth, HomeConnectDevice
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_VALUE,
|
ATTR_VALUE,
|
||||||
@ -35,6 +37,7 @@ from .const import (
|
|||||||
REFRIGERATION_EXTERNAL_LIGHT_POWER,
|
REFRIGERATION_EXTERNAL_LIGHT_POWER,
|
||||||
REFRIGERATION_INTERNAL_LIGHT_BRIGHTNESS,
|
REFRIGERATION_INTERNAL_LIGHT_BRIGHTNESS,
|
||||||
REFRIGERATION_INTERNAL_LIGHT_POWER,
|
REFRIGERATION_INTERNAL_LIGHT_POWER,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID,
|
||||||
)
|
)
|
||||||
from .entity import HomeConnectEntity
|
from .entity import HomeConnectEntity
|
||||||
|
|
||||||
@ -149,8 +152,14 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
|
|||||||
self.device.appliance.set_setting, self.bsh_key, True
|
self.device.appliance.set_setting, self.bsh_key, True
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to turn on light: %s", err)
|
raise ServiceValidationError(
|
||||||
return
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="turn_on_light",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
if self._custom_color_key:
|
if self._custom_color_key:
|
||||||
if (
|
if (
|
||||||
ATTR_RGB_COLOR in kwargs or ATTR_HS_COLOR in kwargs
|
ATTR_RGB_COLOR in kwargs or ATTR_HS_COLOR in kwargs
|
||||||
@ -162,8 +171,14 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
|
|||||||
self._enable_custom_color_value_key,
|
self._enable_custom_color_value_key,
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying selecting custom color: %s", err)
|
raise ServiceValidationError(
|
||||||
return
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="select_light_custom_color",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
|
|
||||||
if ATTR_RGB_COLOR in kwargs:
|
if ATTR_RGB_COLOR in kwargs:
|
||||||
hex_val = color_util.color_rgb_to_hex(*kwargs[ATTR_RGB_COLOR])
|
hex_val = color_util.color_rgb_to_hex(*kwargs[ATTR_RGB_COLOR])
|
||||||
@ -174,7 +189,14 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
|
|||||||
f"#{hex_val}",
|
f"#{hex_val}",
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying setting the color: %s", err)
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="set_light_color",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
elif (ATTR_BRIGHTNESS in kwargs or ATTR_HS_COLOR in kwargs) and (
|
elif (ATTR_BRIGHTNESS in kwargs or ATTR_HS_COLOR in kwargs) and (
|
||||||
self._attr_brightness is not None or ATTR_BRIGHTNESS in kwargs
|
self._attr_brightness is not None or ATTR_BRIGHTNESS in kwargs
|
||||||
):
|
):
|
||||||
@ -199,7 +221,14 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
|
|||||||
f"#{hex_val}",
|
f"#{hex_val}",
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying setting the color: %s", err)
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="set_light_color",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
|
|
||||||
elif self._brightness_key and ATTR_BRIGHTNESS in kwargs:
|
elif self._brightness_key and ATTR_BRIGHTNESS in kwargs:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
@ -217,7 +246,14 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
|
|||||||
self.device.appliance.set_setting, self._brightness_key, brightness
|
self.device.appliance.set_setting, self._brightness_key, brightness
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying set the brightness: %s", err)
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="set_light_brightness",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
|
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
|
|
||||||
@ -229,7 +265,14 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
|
|||||||
self.device.appliance.set_setting, self.bsh_key, False
|
self.device.appliance.set_setting, self.bsh_key, False
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to turn off light: %s", err)
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="turn_off_light",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
|
@ -13,10 +13,21 @@ from homeassistant.components.number import (
|
|||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import get_dict_from_home_connect_error
|
||||||
from .api import ConfigEntryAuth
|
from .api import ConfigEntryAuth
|
||||||
from .const import ATTR_CONSTRAINTS, ATTR_STEPSIZE, ATTR_UNIT, ATTR_VALUE, DOMAIN
|
from .const import (
|
||||||
|
ATTR_CONSTRAINTS,
|
||||||
|
ATTR_STEPSIZE,
|
||||||
|
ATTR_UNIT,
|
||||||
|
ATTR_VALUE,
|
||||||
|
DOMAIN,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_VALUE,
|
||||||
|
)
|
||||||
from .entity import HomeConnectEntity
|
from .entity import HomeConnectEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -109,13 +120,16 @@ class HomeConnectNumberEntity(HomeConnectEntity, NumberEntity):
|
|||||||
value,
|
value,
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error(
|
raise ServiceValidationError(
|
||||||
"Error setting value %s to %s for %s: %s",
|
translation_domain=DOMAIN,
|
||||||
value,
|
translation_key="set_setting",
|
||||||
self.bsh_key,
|
translation_placeholders={
|
||||||
self.entity_id,
|
**get_dict_from_home_connect_error(err),
|
||||||
err,
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
)
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY: self.bsh_key,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_VALUE: str(value),
|
||||||
|
},
|
||||||
|
) from err
|
||||||
|
|
||||||
async def async_fetch_constraints(self) -> None:
|
async def async_fetch_constraints(self) -> None:
|
||||||
"""Fetch the max and min values and step for the number entity."""
|
"""Fetch the max and min values and step for the number entity."""
|
||||||
|
@ -21,6 +21,50 @@
|
|||||||
"default": "[%key:common::config_flow::create_entry::authenticated%]"
|
"default": "[%key:common::config_flow::create_entry::authenticated%]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"exceptions": {
|
||||||
|
"turn_on_light": {
|
||||||
|
"message": "Error while trying to turn on {entity_id}: {description}"
|
||||||
|
},
|
||||||
|
"turn_off_light": {
|
||||||
|
"message": "Error while trying to turn off {entity_id}: {description}"
|
||||||
|
},
|
||||||
|
"set_light_brightness": {
|
||||||
|
"message": "Error while trying to set brightness of {entity_id}: {description}"
|
||||||
|
},
|
||||||
|
"select_light_custom_color": {
|
||||||
|
"message": "Error while trying to select custom color of {entity_id}: {description}"
|
||||||
|
},
|
||||||
|
"set_light_color": {
|
||||||
|
"message": "Error while trying to set color of {entity_id}: {description}"
|
||||||
|
},
|
||||||
|
"set_light_effect": {
|
||||||
|
"message": "Error while trying to set effect of {entity_id}: {description}"
|
||||||
|
},
|
||||||
|
"set_setting": {
|
||||||
|
"message": "Error while trying to set \"{value}\" to \"{key}\" setting for {entity_id}: {description}"
|
||||||
|
},
|
||||||
|
"turn_on": {
|
||||||
|
"message": "Error while trying to turn on {entity_id} ({key}): {description}"
|
||||||
|
},
|
||||||
|
"turn_off": {
|
||||||
|
"message": "Error while trying to turn off {entity_id} ({key}): {description}"
|
||||||
|
},
|
||||||
|
"start_program": {
|
||||||
|
"message": "Error while trying to start program {program}: {description}"
|
||||||
|
},
|
||||||
|
"stop_program": {
|
||||||
|
"message": "Error while trying to stop program {program}: {description}"
|
||||||
|
},
|
||||||
|
"power_on": {
|
||||||
|
"message": "Error while trying to turn on {appliance_name}: {description}"
|
||||||
|
},
|
||||||
|
"power_off": {
|
||||||
|
"message": "Error while trying to turn off {appliance_name} with value \"{value}\": {description}"
|
||||||
|
},
|
||||||
|
"turn_off_not_supported": {
|
||||||
|
"message": "{appliance_name} does not support turning off or entering standby mode."
|
||||||
|
}
|
||||||
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"start_program": {
|
"start_program": {
|
||||||
"name": "Start program",
|
"name": "Start program",
|
||||||
|
@ -9,8 +9,10 @@ from homeconnect.api import HomeConnectError
|
|||||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import get_dict_from_home_connect_error
|
||||||
from .api import ConfigEntryAuth
|
from .api import ConfigEntryAuth
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_VALUE,
|
ATTR_VALUE,
|
||||||
@ -25,6 +27,10 @@ from .const import (
|
|||||||
REFRIGERATION_DISPENSER,
|
REFRIGERATION_DISPENSER,
|
||||||
REFRIGERATION_SUPERMODEFREEZER,
|
REFRIGERATION_SUPERMODEFREEZER,
|
||||||
REFRIGERATION_SUPERMODEREFRIGERATOR,
|
REFRIGERATION_SUPERMODEREFRIGERATOR,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_APPLIANCE_NAME,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_VALUE,
|
||||||
)
|
)
|
||||||
from .entity import HomeConnectDevice, HomeConnectEntity
|
from .entity import HomeConnectDevice, HomeConnectEntity
|
||||||
|
|
||||||
@ -139,9 +145,16 @@ class HomeConnectSwitch(HomeConnectEntity, SwitchEntity):
|
|||||||
self.device.appliance.set_setting, self.entity_description.key, True
|
self.device.appliance.set_setting, self.entity_description.key, True
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to turn on: %s", err)
|
|
||||||
self._attr_available = False
|
self._attr_available = False
|
||||||
return
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="turn_on",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY: self.bsh_key,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
|
|
||||||
self._attr_available = True
|
self._attr_available = True
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
@ -157,7 +170,15 @@ class HomeConnectSwitch(HomeConnectEntity, SwitchEntity):
|
|||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to turn off: %s", err)
|
_LOGGER.error("Error while trying to turn off: %s", err)
|
||||||
self._attr_available = False
|
self._attr_available = False
|
||||||
return
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="turn_off",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY: self.bsh_key,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
|
|
||||||
self._attr_available = True
|
self._attr_available = True
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
@ -200,7 +221,14 @@ class HomeConnectProgramSwitch(HomeConnectEntity, SwitchEntity):
|
|||||||
self.device.appliance.start_program, self.program_name
|
self.device.appliance.start_program, self.program_name
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to start program: %s", err)
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="start_program",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
"program": self.program_name,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
@ -209,7 +237,14 @@ class HomeConnectProgramSwitch(HomeConnectEntity, SwitchEntity):
|
|||||||
try:
|
try:
|
||||||
await self.hass.async_add_executor_job(self.device.appliance.stop_program)
|
await self.hass.async_add_executor_job(self.device.appliance.stop_program)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to stop program: %s", err)
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="stop_program",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
"program": self.program_name,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
@ -255,15 +290,27 @@ class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
|
|||||||
self.device.appliance.set_setting, BSH_POWER_STATE, BSH_POWER_ON
|
self.device.appliance.set_setting, BSH_POWER_STATE, BSH_POWER_ON
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to turn on device: %s", err)
|
|
||||||
self._attr_is_on = False
|
self._attr_is_on = False
|
||||||
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="power_on",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_APPLIANCE_NAME: self.device.appliance.name,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Switch the device off."""
|
"""Switch the device off."""
|
||||||
if self.power_off_state is None:
|
if self.power_off_state is None:
|
||||||
_LOGGER.debug("This appliance type does not support turning off")
|
raise ServiceValidationError(
|
||||||
return
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="turn_off_not_supported",
|
||||||
|
translation_placeholders={
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_APPLIANCE_NAME: self.device.appliance.name
|
||||||
|
},
|
||||||
|
)
|
||||||
_LOGGER.debug("tried to switch off %s", self.name)
|
_LOGGER.debug("tried to switch off %s", self.name)
|
||||||
try:
|
try:
|
||||||
await self.hass.async_add_executor_job(
|
await self.hass.async_add_executor_job(
|
||||||
@ -272,8 +319,16 @@ class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
|
|||||||
self.power_off_state,
|
self.power_off_state,
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error("Error while trying to turn off device: %s", err)
|
|
||||||
self._attr_is_on = True
|
self._attr_is_on = True
|
||||||
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="power_off",
|
||||||
|
translation_placeholders={
|
||||||
|
**get_dict_from_home_connect_error(err),
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_APPLIANCE_NAME: self.device.appliance.name,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_VALUE: self.power_off_state,
|
||||||
|
},
|
||||||
|
) from err
|
||||||
self.async_entity_update()
|
self.async_entity_update()
|
||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
|
@ -8,10 +8,18 @@ from homeconnect.api import HomeConnectError
|
|||||||
from homeassistant.components.time import TimeEntity, TimeEntityDescription
|
from homeassistant.components.time import TimeEntity, TimeEntityDescription
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import get_dict_from_home_connect_error
|
||||||
from .api import ConfigEntryAuth
|
from .api import ConfigEntryAuth
|
||||||
from .const import ATTR_VALUE, DOMAIN
|
from .const import (
|
||||||
|
ATTR_VALUE,
|
||||||
|
DOMAIN,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_VALUE,
|
||||||
|
)
|
||||||
from .entity import HomeConnectEntity
|
from .entity import HomeConnectEntity
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -75,13 +83,16 @@ class HomeConnectTimeEntity(HomeConnectEntity, TimeEntity):
|
|||||||
time_to_seconds(value),
|
time_to_seconds(value),
|
||||||
)
|
)
|
||||||
except HomeConnectError as err:
|
except HomeConnectError as err:
|
||||||
_LOGGER.error(
|
raise ServiceValidationError(
|
||||||
"Error setting value %s to %s for %s: %s",
|
translation_domain=DOMAIN,
|
||||||
value,
|
translation_key="set_setting",
|
||||||
self.bsh_key,
|
translation_placeholders={
|
||||||
self.entity_id,
|
**get_dict_from_home_connect_error(err),
|
||||||
err,
|
SVE_TRANSLATION_PLACEHOLDER_ENTITY_ID: self.entity_id,
|
||||||
)
|
SVE_TRANSLATION_PLACEHOLDER_SETTING_KEY: self.bsh_key,
|
||||||
|
SVE_TRANSLATION_PLACEHOLDER_VALUE: str(value),
|
||||||
|
},
|
||||||
|
) from err
|
||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Update the Time setting status."""
|
"""Update the Time setting status."""
|
||||||
|
@ -27,6 +27,7 @@ from homeassistant.const import (
|
|||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
|
|
||||||
from .conftest import get_all_appliances
|
from .conftest import get_all_appliances
|
||||||
|
|
||||||
@ -232,6 +233,7 @@ async def test_light_functionality(
|
|||||||
"mock_attr",
|
"mock_attr",
|
||||||
"attr_side_effect",
|
"attr_side_effect",
|
||||||
"problematic_appliance",
|
"problematic_appliance",
|
||||||
|
"exception_match",
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
@ -246,6 +248,7 @@ async def test_light_functionality(
|
|||||||
"set_setting",
|
"set_setting",
|
||||||
[HomeConnectError, HomeConnectError],
|
[HomeConnectError, HomeConnectError],
|
||||||
"Hood",
|
"Hood",
|
||||||
|
r"Error.*turn.*on.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"light.hood_functional_light",
|
"light.hood_functional_light",
|
||||||
@ -260,6 +263,7 @@ async def test_light_functionality(
|
|||||||
"set_setting",
|
"set_setting",
|
||||||
[HomeConnectError, HomeConnectError],
|
[HomeConnectError, HomeConnectError],
|
||||||
"Hood",
|
"Hood",
|
||||||
|
r"Error.*turn.*on.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"light.hood_functional_light",
|
"light.hood_functional_light",
|
||||||
@ -271,6 +275,7 @@ async def test_light_functionality(
|
|||||||
"set_setting",
|
"set_setting",
|
||||||
[HomeConnectError, HomeConnectError],
|
[HomeConnectError, HomeConnectError],
|
||||||
"Hood",
|
"Hood",
|
||||||
|
r"Error.*turn.*off.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"light.hood_ambient_light",
|
"light.hood_ambient_light",
|
||||||
@ -285,6 +290,7 @@ async def test_light_functionality(
|
|||||||
"set_setting",
|
"set_setting",
|
||||||
[HomeConnectError, HomeConnectError],
|
[HomeConnectError, HomeConnectError],
|
||||||
"Hood",
|
"Hood",
|
||||||
|
r"Error.*turn.*on.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"light.hood_ambient_light",
|
"light.hood_ambient_light",
|
||||||
@ -299,6 +305,7 @@ async def test_light_functionality(
|
|||||||
"set_setting",
|
"set_setting",
|
||||||
[HomeConnectError, None, HomeConnectError],
|
[HomeConnectError, None, HomeConnectError],
|
||||||
"Hood",
|
"Hood",
|
||||||
|
r"Error.*set.*color.*",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
indirect=["problematic_appliance"],
|
indirect=["problematic_appliance"],
|
||||||
@ -311,6 +318,7 @@ async def test_switch_exception_handling(
|
|||||||
mock_attr: str,
|
mock_attr: str,
|
||||||
attr_side_effect: list,
|
attr_side_effect: list,
|
||||||
problematic_appliance: Mock,
|
problematic_appliance: Mock,
|
||||||
|
exception_match: str,
|
||||||
bypass_throttle: Generator[None],
|
bypass_throttle: Generator[None],
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
integration_setup: Callable[[], Awaitable[bool]],
|
integration_setup: Callable[[], Awaitable[bool]],
|
||||||
@ -333,5 +341,8 @@ async def test_switch_exception_handling(
|
|||||||
|
|
||||||
problematic_appliance.status.update(status)
|
problematic_appliance.status.update(status)
|
||||||
service_data["entity_id"] = entity_id
|
service_data["entity_id"] = entity_id
|
||||||
await hass.services.async_call(LIGHT_DOMAIN, service, service_data, blocking=True)
|
with pytest.raises(ServiceValidationError, match=exception_match):
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN, service, service_data, blocking=True
|
||||||
|
)
|
||||||
assert getattr(problematic_appliance, mock_attr).call_count == len(attr_side_effect)
|
assert getattr(problematic_appliance, mock_attr).call_count == len(attr_side_effect)
|
||||||
|
@ -24,6 +24,7 @@ from homeassistant.components.number import (
|
|||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
|
|
||||||
from .conftest import get_all_appliances
|
from .conftest import get_all_appliances
|
||||||
|
|
||||||
@ -160,6 +161,7 @@ async def test_number_entity_error(
|
|||||||
with pytest.raises(HomeConnectError):
|
with pytest.raises(HomeConnectError):
|
||||||
getattr(problematic_appliance, mock_attr)()
|
getattr(problematic_appliance, mock_attr)()
|
||||||
|
|
||||||
|
with pytest.raises(ServiceValidationError, match=r"Error.*set.*setting.*"):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
NUMBER_DOMAIN,
|
NUMBER_DOMAIN,
|
||||||
SERVICE_SET_VALUE,
|
SERVICE_SET_VALUE,
|
||||||
|
@ -26,6 +26,7 @@ from homeassistant.const import (
|
|||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
|
|
||||||
from .conftest import get_all_appliances
|
from .conftest import get_all_appliances
|
||||||
|
|
||||||
@ -153,7 +154,14 @@ async def test_switch_functionality(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("entity_id", "status", "service", "mock_attr", "problematic_appliance"),
|
(
|
||||||
|
"entity_id",
|
||||||
|
"status",
|
||||||
|
"service",
|
||||||
|
"mock_attr",
|
||||||
|
"problematic_appliance",
|
||||||
|
"exception_match",
|
||||||
|
),
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
"switch.dishwasher_program_mix",
|
"switch.dishwasher_program_mix",
|
||||||
@ -161,6 +169,7 @@ async def test_switch_functionality(
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
"start_program",
|
"start_program",
|
||||||
"Dishwasher",
|
"Dishwasher",
|
||||||
|
r"Error.*start.*program.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"switch.dishwasher_program_mix",
|
"switch.dishwasher_program_mix",
|
||||||
@ -168,6 +177,7 @@ async def test_switch_functionality(
|
|||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
"stop_program",
|
"stop_program",
|
||||||
"Dishwasher",
|
"Dishwasher",
|
||||||
|
r"Error.*stop.*program.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"switch.dishwasher_power",
|
"switch.dishwasher_power",
|
||||||
@ -175,6 +185,7 @@ async def test_switch_functionality(
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
"set_setting",
|
"set_setting",
|
||||||
"Dishwasher",
|
"Dishwasher",
|
||||||
|
r"Error.*turn.*on.*appliance.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"switch.dishwasher_power",
|
"switch.dishwasher_power",
|
||||||
@ -182,6 +193,7 @@ async def test_switch_functionality(
|
|||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
"set_setting",
|
"set_setting",
|
||||||
"Dishwasher",
|
"Dishwasher",
|
||||||
|
r"Error.*turn.*off.*appliance.*value.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"switch.dishwasher_child_lock",
|
"switch.dishwasher_child_lock",
|
||||||
@ -189,6 +201,7 @@ async def test_switch_functionality(
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
"set_setting",
|
"set_setting",
|
||||||
"Dishwasher",
|
"Dishwasher",
|
||||||
|
r"Error.*turn.*on.*key.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"switch.dishwasher_child_lock",
|
"switch.dishwasher_child_lock",
|
||||||
@ -196,6 +209,7 @@ async def test_switch_functionality(
|
|||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
"set_setting",
|
"set_setting",
|
||||||
"Dishwasher",
|
"Dishwasher",
|
||||||
|
r"Error.*turn.*off.*key.*",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
indirect=["problematic_appliance"],
|
indirect=["problematic_appliance"],
|
||||||
@ -205,6 +219,7 @@ async def test_switch_exception_handling(
|
|||||||
status: dict,
|
status: dict,
|
||||||
service: str,
|
service: str,
|
||||||
mock_attr: str,
|
mock_attr: str,
|
||||||
|
exception_match: str,
|
||||||
bypass_throttle: Generator[None],
|
bypass_throttle: Generator[None],
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
integration_setup: Callable[[], Awaitable[bool]],
|
integration_setup: Callable[[], Awaitable[bool]],
|
||||||
@ -227,6 +242,7 @@ async def test_switch_exception_handling(
|
|||||||
with pytest.raises(HomeConnectError):
|
with pytest.raises(HomeConnectError):
|
||||||
getattr(problematic_appliance, mock_attr)()
|
getattr(problematic_appliance, mock_attr)()
|
||||||
|
|
||||||
|
with pytest.raises(ServiceValidationError, match=exception_match):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
SWITCH_DOMAIN, service, {"entity_id": entity_id}, blocking=True
|
SWITCH_DOMAIN, service, {"entity_id": entity_id}, blocking=True
|
||||||
)
|
)
|
||||||
@ -289,7 +305,14 @@ async def test_ent_desc_switch_functionality(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("entity_id", "status", "service", "mock_attr", "problematic_appliance"),
|
(
|
||||||
|
"entity_id",
|
||||||
|
"status",
|
||||||
|
"service",
|
||||||
|
"mock_attr",
|
||||||
|
"problematic_appliance",
|
||||||
|
"exception_match",
|
||||||
|
),
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
"switch.fridgefreezer_freezer_super_mode",
|
"switch.fridgefreezer_freezer_super_mode",
|
||||||
@ -297,6 +320,7 @@ async def test_ent_desc_switch_functionality(
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
"set_setting",
|
"set_setting",
|
||||||
"FridgeFreezer",
|
"FridgeFreezer",
|
||||||
|
r"Error.*turn.*on.*key.*",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"switch.fridgefreezer_freezer_super_mode",
|
"switch.fridgefreezer_freezer_super_mode",
|
||||||
@ -304,6 +328,7 @@ async def test_ent_desc_switch_functionality(
|
|||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
"set_setting",
|
"set_setting",
|
||||||
"FridgeFreezer",
|
"FridgeFreezer",
|
||||||
|
r"Error.*turn.*off.*key.*",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
indirect=["problematic_appliance"],
|
indirect=["problematic_appliance"],
|
||||||
@ -313,6 +338,7 @@ async def test_ent_desc_switch_exception_handling(
|
|||||||
status: dict,
|
status: dict,
|
||||||
service: str,
|
service: str,
|
||||||
mock_attr: str,
|
mock_attr: str,
|
||||||
|
exception_match: str,
|
||||||
bypass_throttle: Generator[None],
|
bypass_throttle: Generator[None],
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
integration_setup: Callable[[], Awaitable[bool]],
|
integration_setup: Callable[[], Awaitable[bool]],
|
||||||
@ -341,6 +367,7 @@ async def test_ent_desc_switch_exception_handling(
|
|||||||
getattr(problematic_appliance, mock_attr)()
|
getattr(problematic_appliance, mock_attr)()
|
||||||
|
|
||||||
problematic_appliance.status.update(status)
|
problematic_appliance.status.update(status)
|
||||||
|
with pytest.raises(ServiceValidationError, match=exception_match):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
SWITCH_DOMAIN, service, {ATTR_ENTITY_ID: entity_id}, blocking=True
|
SWITCH_DOMAIN, service, {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||||
)
|
)
|
||||||
|
@ -12,6 +12,7 @@ from homeassistant.components.time import DOMAIN as TIME_DOMAIN, SERVICE_SET_VAL
|
|||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TIME, Platform
|
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TIME, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
|
|
||||||
from .conftest import get_all_appliances
|
from .conftest import get_all_appliances
|
||||||
|
|
||||||
@ -134,6 +135,7 @@ async def test_time_entity_error(
|
|||||||
with pytest.raises(HomeConnectError):
|
with pytest.raises(HomeConnectError):
|
||||||
getattr(problematic_appliance, mock_attr)()
|
getattr(problematic_appliance, mock_attr)()
|
||||||
|
|
||||||
|
with pytest.raises(ServiceValidationError, match=r"Error.*set.*setting.*"):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
TIME_DOMAIN,
|
TIME_DOMAIN,
|
||||||
SERVICE_SET_VALUE,
|
SERVICE_SET_VALUE,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user