Updated the AlexaModeController to support the remote domain. Also added an alexa entitiy adapter for the remote domain.

This commit is contained in:
tim
2024-06-16 00:36:54 +00:00
parent 9065042960
commit 97a7a2314d
4 changed files with 61 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ from homeassistant.components import (
light, light,
media_player, media_player,
number, number,
remote,
timer, timer,
vacuum, vacuum,
valve, valve,
@@ -439,6 +440,8 @@ class AlexaPowerController(AlexaCapability):
is_on = self.entity.state == fan.STATE_ON is_on = self.entity.state == fan.STATE_ON
elif self.entity.domain == humidifier.DOMAIN: elif self.entity.domain == humidifier.DOMAIN:
is_on = self.entity.state == humidifier.STATE_ON is_on = self.entity.state == humidifier.STATE_ON
elif self.entity.domain == remote.DOMAIN:
is_on = self.entity.state == remote.STATE_ON
elif self.entity.domain == vacuum.DOMAIN: elif self.entity.domain == vacuum.DOMAIN:
is_on = self.entity.state == vacuum.STATE_CLEANING is_on = self.entity.state == vacuum.STATE_CLEANING
elif self.entity.domain == timer.DOMAIN: elif self.entity.domain == timer.DOMAIN:
@@ -1436,6 +1439,12 @@ class AlexaModeController(AlexaCapability):
if mode in modes: if mode in modes:
return f"{humidifier.ATTR_MODE}.{mode}" return f"{humidifier.ATTR_MODE}.{mode}"
# Remote Activity
if self.instance == f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}":
mode = self.entity.attributes.get(remote.ATTR_CURRENT_ACTIVITY, None)
if mode in self.entity.attributes.get(remote.ATTR_ACTIVITY_LIST, None):
return f"{remote.ATTR_ACTIVITY}.{mode}"
# Water heater operation mode # Water heater operation mode
if self.instance == f"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}": if self.instance == f"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}":
operation_mode = self.entity.attributes.get( operation_mode = self.entity.attributes.get(
@@ -1550,6 +1559,22 @@ class AlexaModeController(AlexaCapability):
) )
return self._resource.serialize_capability_resources() return self._resource.serialize_capability_resources()
# 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 []
for activity in activities:
self._resource.add_mode(
f"{remote.ATTR_ACTIVITY}.{activity}", [activity]
)
# Remotes with a single preset_mode completely break Alexa discovery, add a
# fake preset (see issue #53832).
if len(activities) == 1:
self._resource.add_mode(
f"{remote.ATTR_PRESET_MODE}.{PRESET_MODE_NA}", [PRESET_MODE_NA]
)
return self._resource.serialize_capability_resources()
# Cover Position Resources # Cover Position Resources
if self.instance == f"{cover.DOMAIN}.{cover.ATTR_POSITION}": if self.instance == f"{cover.DOMAIN}.{cover.ATTR_POSITION}":
self._resource = AlexaModeResource( self._resource = AlexaModeResource(

View File

@@ -88,7 +88,7 @@ API_THERMOSTAT_MODES_CUSTOM = {
API_THERMOSTAT_PRESETS = {climate.PRESET_ECO: "ECO"} API_THERMOSTAT_PRESETS = {climate.PRESET_ECO: "ECO"}
# AlexaModeController does not like a single mode for the fan preset or humidifier mode, # AlexaModeController does not like a single mode for the fan preset or humidifier mode,
# we add PRESET_MODE_NA if a fan / humidifier has only one preset_mode # we add PRESET_MODE_NA if a fan / humidifier / remote has only one preset_mode
PRESET_MODE_NA = "-" PRESET_MODE_NA = "-"
STORAGE_ACCESS_TOKEN = "access_token" STORAGE_ACCESS_TOKEN = "access_token"

View File

@@ -29,6 +29,7 @@ from homeassistant.components import (
lock, lock,
media_player, media_player,
number, number,
remote,
scene, scene,
script, script,
sensor, sensor,
@@ -647,6 +648,24 @@ class FanCapabilities(AlexaEntity):
yield Alexa(self.entity) yield Alexa(self.entity)
@ENTITY_ADAPTERS.register(remote.DOMAIN)
class RemoteCapabilities(AlexaEntity):
"""Class to represent Remote capabilities."""
def default_display_categories(self) -> list[str]:
"""Return the display categories for this entity."""
return [DisplayCategory.TV]
def interfaces(self) -> Generator[AlexaCapability]:
"""Yield the supported interfaces."""
yield AlexaPowerController(self.entity)
yield AlexaModeController(
self.entity, instance=f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}"
)
yield AlexaEndpointHealth(self.hass, self.entity)
yield Alexa(self.entity)
@ENTITY_ADAPTERS.register(humidifier.DOMAIN) @ENTITY_ADAPTERS.register(humidifier.DOMAIN)
class HumidifierCapabilities(AlexaEntity): class HumidifierCapabilities(AlexaEntity):
"""Class to represent Humidifier capabilities.""" """Class to represent Humidifier capabilities."""

View File

@@ -21,6 +21,7 @@ from homeassistant.components import (
light, light,
media_player, media_player,
number, number,
remote,
timer, timer,
vacuum, vacuum,
valve, valve,
@@ -185,6 +186,8 @@ async def async_api_turn_on(
service = fan.SERVICE_TURN_ON service = fan.SERVICE_TURN_ON
elif domain == humidifier.DOMAIN: elif domain == humidifier.DOMAIN:
service = humidifier.SERVICE_TURN_ON service = humidifier.SERVICE_TURN_ON
elif domain == remote.DOMAIN:
service = remote.SERVICE_TURN_ON
elif domain == vacuum.DOMAIN: elif domain == vacuum.DOMAIN:
supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if ( if (
@@ -234,6 +237,8 @@ async def async_api_turn_off(
service = climate.SERVICE_TURN_OFF service = climate.SERVICE_TURN_OFF
elif domain == fan.DOMAIN: elif domain == fan.DOMAIN:
service = fan.SERVICE_TURN_OFF service = fan.SERVICE_TURN_OFF
elif domain == remote.DOMAIN:
service = remote.SERVICE_TURN_OFF
elif domain == humidifier.DOMAIN: elif domain == humidifier.DOMAIN:
service = humidifier.SERVICE_TURN_OFF service = humidifier.SERVICE_TURN_OFF
elif domain == vacuum.DOMAIN: elif domain == vacuum.DOMAIN:
@@ -1200,6 +1205,17 @@ async def async_api_set_mode(
msg = f"Entity '{entity.entity_id}' does not support Mode '{mode}'" msg = f"Entity '{entity.entity_id}' does not support Mode '{mode}'"
raise AlexaInvalidValueError(msg) raise AlexaInvalidValueError(msg)
# Remote Activity
if instance == f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}":
activity = mode.split(".")[1]
activities: list[str] | None = entity.attributes.get(remote.ATTR_ACTIVITY_LIST)
if activity != PRESET_MODE_NA and activities and preset_mode in activities:
service = remote.SERVICE_TURN_ON
data[remote.ATTR_ACTIVITY] = activity
else:
msg = f"Entity '{entity.entity_id}' does not support Mode '{mode}'"
raise AlexaInvalidValueError(msg)
# Water heater operation mode # Water heater operation mode
elif instance == f"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}": elif instance == f"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}":
operation_mode = mode.split(".")[1] operation_mode = mode.split(".")[1]