mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Implement supported locales for Alexa capabilities (#30285)
* Implement Alexa capability supported locales. * Check config for supported locales. * Removed unused import. * Applied some potpourri to improve code smell. * Change supported_locales to set.
This commit is contained in:
parent
80701c8f2a
commit
6387a50697
@ -17,6 +17,8 @@ from .const import (
|
||||
CONF_ENDPOINT,
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_FILTER,
|
||||
CONF_LOCALE,
|
||||
CONF_SUPPORTED_LOCALES,
|
||||
CONF_TEXT,
|
||||
CONF_TITLE,
|
||||
CONF_UID,
|
||||
@ -27,6 +29,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_FLASH_BRIEFINGS = "flash_briefings"
|
||||
CONF_SMART_HOME = "smart_home"
|
||||
DEFAULT_LOCALE = "en-US"
|
||||
|
||||
ALEXA_ENTITY_SCHEMA = vol.Schema(
|
||||
{
|
||||
@ -41,6 +44,9 @@ SMART_HOME_SCHEMA = vol.Schema(
|
||||
vol.Optional(CONF_ENDPOINT): cv.string,
|
||||
vol.Optional(CONF_CLIENT_ID): cv.string,
|
||||
vol.Optional(CONF_CLIENT_SECRET): cv.string,
|
||||
vol.Optional(CONF_LOCALE, default=DEFAULT_LOCALE): vol.In(
|
||||
CONF_SUPPORTED_LOCALES
|
||||
),
|
||||
vol.Optional(CONF_FILTER, default={}): entityfilter.FILTER_SCHEMA,
|
||||
vol.Optional(CONF_ENTITY_CONFIG): {cv.entity_id: ALEXA_ENTITY_SCHEMA},
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ class AlexaCapability:
|
||||
https://developer.amazon.com/docs/device-apis/message-guide.html
|
||||
"""
|
||||
|
||||
supported_locales = {"en-US"}
|
||||
|
||||
def __init__(self, entity, instance=None):
|
||||
"""Initialize an Alexa capability."""
|
||||
self.entity = entity
|
||||
@ -239,6 +241,21 @@ class Alexa(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-interface.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"fr-CA",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa"
|
||||
@ -250,6 +267,19 @@ class AlexaEndpointHealth(AlexaCapability):
|
||||
https://developer.amazon.com/docs/smarthome/state-reporting-for-a-smart-home-skill.html#report-state-when-alexa-requests-it
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def __init__(self, hass, entity):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -287,6 +317,19 @@ class AlexaPowerController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.PowerController"
|
||||
@ -323,6 +366,17 @@ class AlexaLockController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-lockcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.LockController"
|
||||
@ -357,6 +411,17 @@ class AlexaSceneController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-scenecontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
}
|
||||
|
||||
def __init__(self, entity, supports_deactivation):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -373,6 +438,19 @@ class AlexaBrightnessController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-brightnesscontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.BrightnessController"
|
||||
@ -404,6 +482,19 @@ class AlexaColorController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-colorcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.ColorController"
|
||||
@ -436,6 +527,19 @@ class AlexaColorTemperatureController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-colortemperaturecontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.ColorTemperatureController"
|
||||
@ -465,6 +569,19 @@ class AlexaPercentageController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-percentagecontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.PercentageController"
|
||||
@ -499,6 +616,8 @@ class AlexaSpeaker(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-speaker.html
|
||||
"""
|
||||
|
||||
supported_locales = {"de-DE", "en-AU", "en-CA", "en-GB", "en-IN", "en-US"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.Speaker"
|
||||
@ -510,6 +629,8 @@ class AlexaStepSpeaker(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-stepspeaker.html
|
||||
"""
|
||||
|
||||
supported_locales = {"de-DE", "en-AU", "en-CA", "en-GB", "en-IN", "en-US"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.StepSpeaker"
|
||||
@ -521,6 +642,8 @@ class AlexaPlaybackController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-playbackcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {"de-DE", "en-AU", "en-CA", "en-GB", "en-IN", "en-US", "fr-FR"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.PlaybackController"
|
||||
@ -554,6 +677,8 @@ class AlexaInputController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-inputcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {"de-DE", "en-AU", "en-CA", "en-GB", "en-IN", "en-US"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.InputController"
|
||||
@ -582,6 +707,19 @@ class AlexaTemperatureSensor(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-temperaturesensor.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def __init__(self, hass, entity):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -637,6 +775,8 @@ class AlexaContactSensor(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-contactsensor.html
|
||||
"""
|
||||
|
||||
supported_locales = {"en-CA", "en-US"}
|
||||
|
||||
def __init__(self, hass, entity):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -674,6 +814,8 @@ class AlexaMotionSensor(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-motionsensor.html
|
||||
"""
|
||||
|
||||
supported_locales = {"en-CA", "en-US"}
|
||||
|
||||
def __init__(self, hass, entity):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -711,6 +853,19 @@ class AlexaThermostatController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-thermostatcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def __init__(self, hass, entity):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -819,6 +974,19 @@ class AlexaPowerLevelController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-powerlevelcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.PowerLevelController"
|
||||
@ -854,6 +1022,8 @@ class AlexaSecurityPanelController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-securitypanelcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {"en-AU", "en-CA", "en-IN", "en-US"}
|
||||
|
||||
def __init__(self, hass, entity):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -906,6 +1076,21 @@ class AlexaModeController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-modecontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"fr-CA",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def __init__(self, entity, instance, non_controllable=False):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity, instance)
|
||||
@ -1031,6 +1216,21 @@ class AlexaRangeController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-rangecontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"fr-CA",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def __init__(self, entity, instance, non_controllable=False):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity, instance)
|
||||
@ -1198,6 +1398,21 @@ class AlexaToggleController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-togglecontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"fr-CA",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
}
|
||||
|
||||
def __init__(self, entity, instance, non_controllable=False):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity, instance)
|
||||
@ -1252,6 +1467,8 @@ class AlexaChannelController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-channelcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {"de-DE", "en-AU", "en-CA", "en-GB", "en-IN", "en-US"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.ChannelController"
|
||||
@ -1263,6 +1480,8 @@ class AlexaDoorbellEventSource(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-doorbelleventsource.html
|
||||
"""
|
||||
|
||||
supported_locales = {"en-US"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.DoorbellEventSource"
|
||||
@ -1278,6 +1497,8 @@ class AlexaPlaybackStateReporter(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-playbackstatereporter.html
|
||||
"""
|
||||
|
||||
supported_locales = {"de-DE", "en-GB", "en-US", "fr-FR"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.PlaybackStateReporter"
|
||||
@ -1314,6 +1535,8 @@ class AlexaSeekController(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-seekcontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {"de-DE", "en-GB", "en-US"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.SeekController"
|
||||
@ -1325,6 +1548,8 @@ class AlexaEventDetectionSensor(AlexaCapability):
|
||||
https://developer.amazon.com/docs/device-apis/alexa-eventdetectionsensor.html
|
||||
"""
|
||||
|
||||
supported_locales = {"en-US"}
|
||||
|
||||
def __init__(self, hass, entity):
|
||||
"""Initialize the entity."""
|
||||
super().__init__(entity)
|
||||
@ -1382,6 +1607,8 @@ class AlexaEqualizerController(AlexaCapability):
|
||||
https://developer.amazon.com/en-US/docs/alexa/device-apis/alexa-equalizercontroller.html
|
||||
"""
|
||||
|
||||
supported_locales = {"en-US"}
|
||||
|
||||
def name(self):
|
||||
"""Return the Alexa API name of this interface."""
|
||||
return "Alexa.EqualizerController"
|
||||
|
@ -28,6 +28,11 @@ class AbstractConfig:
|
||||
"""Endpoint for report state."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def locale(self):
|
||||
"""Return config locale."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def entity_config(self):
|
||||
"""Return entity config."""
|
||||
|
@ -19,6 +19,7 @@ CONF_ENTITY_CONFIG = "entity_config"
|
||||
CONF_ENDPOINT = "endpoint"
|
||||
CONF_CLIENT_ID = "client_id"
|
||||
CONF_CLIENT_SECRET = "client_secret"
|
||||
CONF_LOCALE = "locale"
|
||||
|
||||
ATTR_UID = "uid"
|
||||
ATTR_UPDATE_DATE = "updateDate"
|
||||
@ -42,6 +43,20 @@ API_CHANGE = "change"
|
||||
|
||||
CONF_DESCRIPTION = "description"
|
||||
CONF_DISPLAY_CATEGORIES = "display_categories"
|
||||
CONF_SUPPORTED_LOCALES = (
|
||||
"de-DE",
|
||||
"en-AU",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-IN",
|
||||
"en-US",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"fr-CA",
|
||||
"fr-FR",
|
||||
"it-IT",
|
||||
"ja-JP",
|
||||
)
|
||||
|
||||
API_TEMP_UNITS = {TEMP_FAHRENHEIT: "FAHRENHEIT", TEMP_CELSIUS: "CELSIUS"}
|
||||
|
||||
|
@ -260,16 +260,24 @@ class AlexaEntity:
|
||||
|
||||
def serialize_discovery(self):
|
||||
"""Serialize the entity for discovery."""
|
||||
return {
|
||||
result = {
|
||||
"displayCategories": self.display_categories(),
|
||||
"cookie": {},
|
||||
"endpointId": self.alexa_id(),
|
||||
"friendlyName": self.friendly_name(),
|
||||
"description": self.description(),
|
||||
"manufacturerName": "Home Assistant",
|
||||
"capabilities": [i.serialize_discovery() for i in self.interfaces()],
|
||||
}
|
||||
|
||||
locale = self.config.locale
|
||||
capabilities = []
|
||||
for i in self.interfaces():
|
||||
if locale in i.supported_locales:
|
||||
capabilities.append(i.serialize_discovery())
|
||||
result["capabilities"] = capabilities
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@callback
|
||||
def async_get_entities(hass, config) -> List[AlexaEntity]:
|
||||
|
@ -412,6 +412,10 @@ async def async_api_lock(hass, config, directive, context):
|
||||
@HANDLERS.register(("Alexa.LockController", "Unlock"))
|
||||
async def async_api_unlock(hass, config, directive, context):
|
||||
"""Process an unlock request."""
|
||||
if config.locale not in {"de-DE", "en-US", "ja-JP"}:
|
||||
msg = f"The unlock directive is not supported for the following locales: {config.locale}"
|
||||
raise AlexaInvalidDirectiveError(msg)
|
||||
|
||||
entity = directive.entity
|
||||
await hass.services.async_call(
|
||||
entity.domain,
|
||||
|
@ -12,6 +12,7 @@ from .const import (
|
||||
CONF_ENDPOINT,
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_FILTER,
|
||||
CONF_LOCALE,
|
||||
)
|
||||
from .smart_home import async_handle_message
|
||||
from .state_report import async_enable_proactive_mode
|
||||
@ -53,6 +54,11 @@ class AlexaConfig(AbstractConfig):
|
||||
"""Return entity config."""
|
||||
return self._config.get(CONF_ENTITY_CONFIG) or {}
|
||||
|
||||
@property
|
||||
def locale(self):
|
||||
"""Return config locale."""
|
||||
return self._config.get(CONF_LOCALE)
|
||||
|
||||
def should_expose(self, entity_id):
|
||||
"""If an entity should be exposed."""
|
||||
return self._config[CONF_FILTER](entity_id)
|
||||
|
@ -8,6 +8,7 @@ from tests.common import async_mock_service
|
||||
|
||||
TEST_URL = "https://api.amazonalexa.com/v3/events"
|
||||
TEST_TOKEN_URL = "https://api.amazon.com/auth/o2/token"
|
||||
TEST_LOCALE = "en-US"
|
||||
|
||||
|
||||
class MockConfig(config.AbstractConfig):
|
||||
@ -30,6 +31,11 @@ class MockConfig(config.AbstractConfig):
|
||||
"""Endpoint for report state."""
|
||||
return TEST_URL
|
||||
|
||||
@property
|
||||
def locale(self):
|
||||
"""Return config locale."""
|
||||
return TEST_LOCALE
|
||||
|
||||
def should_expose(self, entity_id):
|
||||
"""If an entity should be exposed."""
|
||||
return True
|
||||
|
Loading…
x
Reference in New Issue
Block a user