mirror of
https://github.com/home-assistant/core.git
synced 2025-08-01 03:35:09 +02:00
Updated the CapabilityResource to support labels with the corresponding locale. This local is read from the users config.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from typing_extensions import Generator
|
||||
|
||||
@@ -60,6 +60,9 @@ from homeassistant.core import HomeAssistant, State
|
||||
import homeassistant.util.color as color_util
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .config import AbstractConfig
|
||||
|
||||
from .const import (
|
||||
API_TEMP_UNITS,
|
||||
API_THERMOSTAT_MODES,
|
||||
@@ -126,11 +129,13 @@ class AlexaCapability:
|
||||
self,
|
||||
entity: State,
|
||||
instance: str | None = None,
|
||||
config: AbstractConfig | None = None,
|
||||
non_controllable_properties: bool | None = None,
|
||||
) -> None:
|
||||
"""Initialize an Alexa capability."""
|
||||
self.entity = entity
|
||||
self.instance = instance
|
||||
self.config = config
|
||||
self._non_controllable_properties = non_controllable_properties
|
||||
|
||||
def name(self) -> str:
|
||||
@@ -1390,10 +1395,14 @@ class AlexaModeController(AlexaCapability):
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self, entity: State, instance: str, non_controllable: bool = False
|
||||
self,
|
||||
entity: State,
|
||||
instance: str,
|
||||
config: AbstractConfig,
|
||||
non_controllable: bool = False,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
AlexaCapability.__init__(self, entity, instance, non_controllable)
|
||||
AlexaCapability.__init__(self, entity, instance, config, non_controllable)
|
||||
self._resource = None
|
||||
self._semantics = None
|
||||
|
||||
@@ -1562,10 +1571,13 @@ class AlexaModeController(AlexaCapability):
|
||||
# Remote Resource
|
||||
if self.instance == f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}":
|
||||
self._resource = AlexaModeResource([AlexaGlobalCatalog.SETTING_MODE], False)
|
||||
activities = self.entity.attributes.get(remote.ATTR_ACTIVITY_LIST) or []
|
||||
activities: list[str] = (
|
||||
self.entity.attributes.get(remote.ATTR_ACTIVITY_LIST) or []
|
||||
)
|
||||
locale = self.config.locale if self.config else ""
|
||||
for activity in activities:
|
||||
self._resource.add_mode(
|
||||
f"{remote.ATTR_ACTIVITY}.{activity}", [activity]
|
||||
self._resource.add_mode_with_locale(
|
||||
f"{remote.ATTR_ACTIVITY}.{activity}", {activity: locale or ""}
|
||||
)
|
||||
# Remotes with a single preset_mode completely break Alexa discovery, add a
|
||||
# fake preset (see issue #53832).
|
||||
@@ -1729,7 +1741,7 @@ class AlexaRangeController(AlexaCapability):
|
||||
self, entity: State, instance: str | None, non_controllable: bool = False
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
AlexaCapability.__init__(self, entity, instance, non_controllable)
|
||||
AlexaCapability.__init__(self, entity, instance, None, non_controllable)
|
||||
self._resource = None
|
||||
self._semantics = None
|
||||
|
||||
@@ -2072,7 +2084,7 @@ class AlexaToggleController(AlexaCapability):
|
||||
self, entity: State, instance: str, non_controllable: bool = False
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
AlexaCapability.__init__(self, entity, instance, non_controllable)
|
||||
AlexaCapability.__init__(self, entity, instance, None, non_controllable)
|
||||
self._resource = None
|
||||
self._semantics = None
|
||||
|
||||
|
@@ -504,6 +504,7 @@ class ClimateCapabilities(AlexaEntity):
|
||||
yield AlexaModeController(
|
||||
self.entity,
|
||||
instance=f"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}",
|
||||
config=self.config,
|
||||
)
|
||||
yield AlexaEndpointHealth(self.hass, self.entity)
|
||||
yield Alexa(self.entity)
|
||||
@@ -553,7 +554,9 @@ class CoverCapabilities(AlexaEntity):
|
||||
cover.CoverEntityFeature.CLOSE | cover.CoverEntityFeature.OPEN
|
||||
):
|
||||
yield AlexaModeController(
|
||||
self.entity, instance=f"{cover.DOMAIN}.{cover.ATTR_POSITION}"
|
||||
self.entity,
|
||||
instance=f"{cover.DOMAIN}.{cover.ATTR_POSITION}",
|
||||
config=self.config,
|
||||
)
|
||||
if supported & cover.CoverEntityFeature.SET_TILT_POSITION:
|
||||
yield AlexaRangeController(self.entity, instance=f"{cover.DOMAIN}.tilt")
|
||||
@@ -625,12 +628,16 @@ class FanCapabilities(AlexaEntity):
|
||||
force_range_controller = False
|
||||
if supported & fan.FanEntityFeature.PRESET_MODE:
|
||||
yield AlexaModeController(
|
||||
self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_PRESET_MODE}"
|
||||
self.entity,
|
||||
instance=f"{fan.DOMAIN}.{fan.ATTR_PRESET_MODE}",
|
||||
config=self.config,
|
||||
)
|
||||
force_range_controller = False
|
||||
if supported & fan.FanEntityFeature.DIRECTION:
|
||||
yield AlexaModeController(
|
||||
self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_DIRECTION}"
|
||||
self.entity,
|
||||
instance=f"{fan.DOMAIN}.{fan.ATTR_DIRECTION}",
|
||||
config=self.config,
|
||||
)
|
||||
force_range_controller = False
|
||||
|
||||
@@ -660,7 +667,9 @@ class RemoteCapabilities(AlexaEntity):
|
||||
"""Yield the supported interfaces."""
|
||||
yield AlexaPowerController(self.entity)
|
||||
yield AlexaModeController(
|
||||
self.entity, instance=f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}"
|
||||
self.entity,
|
||||
instance=f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}",
|
||||
config=self.config,
|
||||
)
|
||||
yield AlexaEndpointHealth(self.hass, self.entity)
|
||||
yield Alexa(self.entity)
|
||||
@@ -680,7 +689,9 @@ class HumidifierCapabilities(AlexaEntity):
|
||||
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
if supported & humidifier.HumidifierEntityFeature.MODES:
|
||||
yield AlexaModeController(
|
||||
self.entity, instance=f"{humidifier.DOMAIN}.{humidifier.ATTR_MODE}"
|
||||
self.entity,
|
||||
instance=f"{humidifier.DOMAIN}.{humidifier.ATTR_MODE}",
|
||||
config=self.config,
|
||||
)
|
||||
yield AlexaRangeController(
|
||||
self.entity, instance=f"{humidifier.DOMAIN}.{humidifier.ATTR_HUMIDITY}"
|
||||
@@ -1012,7 +1023,9 @@ class ValveCapabilities(AlexaEntity):
|
||||
elif supported & (
|
||||
valve.ValveEntityFeature.CLOSE | valve.ValveEntityFeature.OPEN
|
||||
):
|
||||
yield AlexaModeController(self.entity, instance=f"{valve.DOMAIN}.state")
|
||||
yield AlexaModeController(
|
||||
self.entity, instance=f"{valve.DOMAIN}.state", config=self.config
|
||||
)
|
||||
if supported & valve.ValveEntityFeature.STOP:
|
||||
yield AlexaToggleController(self.entity, instance=f"{valve.DOMAIN}.stop")
|
||||
yield AlexaEndpointHealth(self.hass, self.entity)
|
||||
|
@@ -211,9 +211,9 @@ class AlexaCapabilityResource:
|
||||
|
||||
def __init__(self, labels: list[str]) -> None:
|
||||
"""Initialize an Alexa resource."""
|
||||
self._resource_labels = []
|
||||
self._resource_labels: dict[str, str] = {}
|
||||
for label in labels:
|
||||
self._resource_labels.append(label)
|
||||
self._resource_labels.update({label: ""})
|
||||
|
||||
def serialize_capability_resources(self) -> dict[str, list[dict[str, Any]]]:
|
||||
"""Return capabilityResources object serialized for an API response."""
|
||||
@@ -226,20 +226,22 @@ class AlexaCapabilityResource:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def serialize_labels(self, resources: list[str]) -> dict[str, list[dict[str, Any]]]:
|
||||
def serialize_labels(
|
||||
self, resources: dict[str, str]
|
||||
) -> dict[str, list[dict[str, Any]]]:
|
||||
"""Return serialized labels for an API response.
|
||||
|
||||
Returns resource label objects for friendlyNames serialized.
|
||||
"""
|
||||
labels: list[dict[str, Any]] = []
|
||||
label_dict: dict[str, Any]
|
||||
for label in resources:
|
||||
for label, locale in resources.items():
|
||||
if label in AlexaGlobalCatalog.__dict__.values():
|
||||
label_dict = {"@type": "asset", "value": {"assetId": label}}
|
||||
else:
|
||||
label_dict = {
|
||||
"@type": "text",
|
||||
"value": {"text": label, "locale": "en-US"},
|
||||
"value": {"text": label, "locale": locale or "en-US"},
|
||||
}
|
||||
|
||||
labels.append(label_dict)
|
||||
@@ -260,6 +262,10 @@ class AlexaModeResource(AlexaCapabilityResource):
|
||||
self._mode_ordered: bool = ordered
|
||||
|
||||
def add_mode(self, value: str, labels: list[str]) -> None:
|
||||
"""Add mode to the supportedModes object."""
|
||||
self.add_mode_with_locale(value, {label: "" for label in labels})
|
||||
|
||||
def add_mode_with_locale(self, value: str, labels: dict[str, str]) -> None:
|
||||
"""Add mode to the supportedModes object."""
|
||||
self._supported_modes.append({"value": value, "labels": labels})
|
||||
|
||||
@@ -307,6 +313,10 @@ class AlexaPresetResource(AlexaCapabilityResource):
|
||||
self._unit_of_measure = unit
|
||||
|
||||
def add_preset(self, value: float, labels: list[str]) -> None:
|
||||
"""Add preset to configuration presets array."""
|
||||
self.add_preset_with_locale(value, {label: "" for label in labels})
|
||||
|
||||
def add_preset_with_locale(self, value: float, labels: dict[str, str]) -> None:
|
||||
"""Add preset to configuration presets array."""
|
||||
self._presets.append({"value": value, "labels": labels})
|
||||
|
||||
|
Reference in New Issue
Block a user