1 """Alexa entity adapters."""
3 from __future__
import annotations
5 from collections.abc
import Generator, Iterable
7 from typing
import TYPE_CHECKING, Any
42 ATTR_SUPPORTED_FEATURES,
43 ATTR_UNIT_OF_MEASUREMENT,
44 CLOUD_NEVER_EXPOSED_ENTITIES,
55 from .capabilities
import (
57 AlexaBrightnessController,
58 AlexaCameraStreamController,
60 AlexaChannelController,
62 AlexaColorTemperatureController,
64 AlexaDoorbellEventSource,
66 AlexaEqualizerController,
67 AlexaEventDetectionSensor,
72 AlexaPlaybackController,
73 AlexaPlaybackStateReporter,
77 AlexaSecurityPanelController,
81 AlexaTemperatureSensor,
82 AlexaThermostatController,
83 AlexaTimeHoldController,
84 AlexaToggleController,
86 from .const
import CONF_DISPLAY_CATEGORIES
89 from .config
import AbstractConfig
91 _LOGGER = logging.getLogger(__name__)
93 ENTITY_ADAPTERS: Registry[str, type[AlexaEntity]] =
Registry()
95 TRANSLATION_TABLE = dict.fromkeys(map(ord,
r"}{\/|\"()[]+~!><*%"),
None)
99 """Possible display categories for Discovery response.
101 https://developer.amazon.com/docs/device-apis/alexa-discovery.html#display-categories
108 ACTIVITY_TRIGGER =
"ACTIVITY_TRIGGER"
111 AIR_CONDITIONER =
"AIR_CONDITIONER"
115 AIR_FRESHENER =
"AIR_FRESHENER"
118 AIR_PURIFIER =
"AIR_PURIFIER"
121 AUTO_ACCESSORY =
"AUTO_ACCESSORY"
127 CHRISTMAS_TREE =
"CHRISTMAS_TREE"
130 COFFEE_MAKER =
"COFFEE_MAKER"
133 COMPUTER =
"COMPUTER"
136 CONTACT_SENSOR =
"CONTACT_SENSOR"
142 DOORBELL =
"DOORBELL"
145 EXTERIOR_BLIND =
"EXTERIOR_BLIND"
151 GAME_CONSOLE =
"GAME_CONSOLE"
156 GARAGE_DOOR =
"GARAGE_DOOR"
159 HEADPHONES =
"HEADPHONES"
165 INTERIOR_BLIND =
"INTERIOR_BLIND"
174 MICROWAVE =
"MICROWAVE"
177 MOBILE_PHONE =
"MOBILE_PHONE"
180 MOTION_SENSOR =
"MOTION_SENSOR"
183 MUSIC_SYSTEM =
"MUSIC_SYSTEM"
186 NETWORK_HARDWARE =
"NETWORK_HARDWARE"
211 SCENE_TRIGGER =
"SCENE_TRIGGER"
217 SECURITY_PANEL =
"SECURITY_PANEL"
220 SECURITY_SYSTEM =
"SECURITY_SYSTEM"
224 SLOW_COOKER =
"SLOW_COOKER"
227 SMARTLOCK =
"SMARTLOCK"
231 SMARTPLUG =
"SMARTPLUG"
237 STREAMING_DEVICE =
"STREAMING_DEVICE"
247 TEMPERATURE_SENSOR =
"TEMPERATURE_SENSOR"
251 THERMOSTAT =
"THERMOSTAT"
257 VACUUM_CLEANER =
"VACUUM_CLEANER"
260 WATER_HEATER =
"WATER_HEATER"
264 WEARABLE =
"WEARABLE"
268 """An adaptation of an entity, expressed in Alexa's terms.
270 The API handlers should manipulate entities only through this interface.
274 self, hass: HomeAssistant, config: AbstractConfig, entity: State
276 """Initialize Alexa Entity."""
280 self.
entity_confentity_conf = config.entity_config.get(entity.entity_id, {})
284 """Return the Entity ID."""
285 return self.
entityentity.entity_id
288 """Return the Alexa API friendly name."""
290 CONF_NAME, self.
entityentity.name
291 ).translate(TRANSLATION_TABLE)
295 """Return the Alexa API description."""
297 return f
"{description} via Home Assistant".translate(TRANSLATION_TABLE)
300 """Return the Alexa API entity id."""
301 return self.
configconfig.generate_alexa_id(self.
entityentity.entity_id)
304 """Return a list of display categories."""
305 entity_conf = self.
configconfig.entity_config.get(self.
entityentity.entity_id, {})
306 if CONF_DISPLAY_CATEGORIES
in entity_conf:
307 return [entity_conf[CONF_DISPLAY_CATEGORIES]]
311 """Return a list of default display categories.
313 This can be overridden by the user in the Home Assistant configuration.
315 See also DisplayCategory.
317 raise NotImplementedError
320 """Return a list of supported interfaces.
322 Used for discovery. The list should contain AlexaInterface instances.
323 If the list is empty, this entity will not be discovered.
325 raise NotImplementedError
328 """Yield each supported property in API format."""
330 if not interface.properties_proactively_reported():
333 yield from interface.serialize_properties()
336 """Serialize the entity for discovery."""
337 result: dict[str, Any] = {
340 "endpointId": self.
alexa_idalexa_id(),
343 "manufacturerName":
"Home Assistant",
344 "additionalAttributes": {
345 "manufacturer":
"Home Assistant",
346 "model": self.
entityentity.domain,
347 "softwareVersion": __version__,
348 "customIdentifier": f
"{self.config.user_identifier()}-{self.entity_id}",
352 locale = self.
configconfig.locale
356 if locale
not in i.supported_locales:
360 capabilities.append(i.serialize_discovery())
363 "Error serializing %s discovery for %s", i.name(), self.
entityentity
366 result[
"capabilities"] = capabilities
373 hass: HomeAssistant, config: AbstractConfig
374 ) -> list[AlexaEntity]:
375 """Return all entities that are supported by Alexa."""
376 entities: list[AlexaEntity] = []
377 for state
in hass.states.async_all():
378 if state.entity_id
in CLOUD_NEVER_EXPOSED_ENTITIES:
381 if state.domain
not in ENTITY_ADAPTERS:
385 alexa_entity = ENTITY_ADAPTERS[state.domain](hass, config, state)
386 interfaces =
list(alexa_entity.interfaces())
388 _LOGGER.exception(
"Unable to serialize %s for discovery", state.entity_id)
392 entities.append(alexa_entity)
397 @ENTITY_ADAPTERS.register(alert.DOMAIN)
398 @ENTITY_ADAPTERS.register(automation.DOMAIN)
399 @ENTITY_ADAPTERS.register(group.DOMAIN)
401 """A generic, on/off device.
403 The choice of last resort.
407 """Return the display categories for this entity."""
408 if self.
entityentity.domain == automation.DOMAIN:
409 return [DisplayCategory.ACTIVITY_TRIGGER]
411 return [DisplayCategory.OTHER]
414 """Yield the supported interfaces."""
420 @ENTITY_ADAPTERS.register(input_boolean.DOMAIN)
421 @ENTITY_ADAPTERS.register(switch.DOMAIN)
423 """Class to represent Switch capabilities."""
426 """Return the display categories for this entity."""
427 if self.
entityentity.domain == input_boolean.DOMAIN:
428 return [DisplayCategory.OTHER]
430 device_class = self.
entityentity.attributes.get(ATTR_DEVICE_CLASS)
431 if device_class == switch.SwitchDeviceClass.OUTLET:
432 return [DisplayCategory.SMARTPLUG]
434 return [DisplayCategory.SWITCH]
437 """Yield the supported interfaces."""
444 @ENTITY_ADAPTERS.register(button.DOMAIN)
445 @ENTITY_ADAPTERS.register(input_button.DOMAIN)
447 """Class to represent Button capabilities."""
450 """Return the display categories for this entity."""
451 return [DisplayCategory.ACTIVITY_TRIGGER]
454 """Yield the supported interfaces."""
461 @ENTITY_ADAPTERS.register(climate.DOMAIN)
462 @ENTITY_ADAPTERS.register(water_heater.DOMAIN)
464 """Class to represent Climate capabilities."""
467 """Return the display categories for this entity."""
468 if self.
entityentity.domain == water_heater.DOMAIN:
469 return [DisplayCategory.WATER_HEATER]
470 return [DisplayCategory.THERMOSTAT]
473 """Yield the supported interfaces."""
475 supported_features = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
477 self.
entityentity.domain == climate.DOMAIN
478 and climate.HVACMode.OFF
479 in (self.
entityentity.attributes.get(climate.ATTR_HVAC_MODES)
or [])
480 or self.
entityentity.domain == climate.DOMAIN
484 climate.ClimateEntityFeature.TURN_ON
485 | climate.ClimateEntityFeature.TURN_OFF
488 or self.
entityentity.domain == water_heater.DOMAIN
489 and (supported_features & water_heater.WaterHeaterEntityFeature.ON_OFF)
494 self.
entityentity.domain == climate.DOMAIN
495 or self.
entityentity.domain == water_heater.DOMAIN
498 & water_heater.WaterHeaterEntityFeature.OPERATION_MODE
503 if self.
entityentity.domain == water_heater.DOMAIN
and (
504 supported_features & water_heater.WaterHeaterEntityFeature.OPERATION_MODE
508 instance=f
"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}",
514 @ENTITY_ADAPTERS.register(cover.DOMAIN)
516 """Class to represent Cover capabilities."""
519 """Return the display categories for this entity."""
520 device_class = self.
entityentity.attributes.get(ATTR_DEVICE_CLASS)
521 if device_class
in (cover.CoverDeviceClass.GARAGE, cover.CoverDeviceClass.GATE):
522 return [DisplayCategory.GARAGE_DOOR]
523 if device_class == cover.CoverDeviceClass.DOOR:
524 return [DisplayCategory.DOOR]
526 cover.CoverDeviceClass.BLIND,
527 cover.CoverDeviceClass.SHADE,
528 cover.CoverDeviceClass.CURTAIN,
530 return [DisplayCategory.INTERIOR_BLIND]
532 cover.CoverDeviceClass.WINDOW,
533 cover.CoverDeviceClass.AWNING,
534 cover.CoverDeviceClass.SHUTTER,
536 return [DisplayCategory.EXTERIOR_BLIND]
538 return [DisplayCategory.OTHER]
541 """Yield the supported interfaces."""
542 device_class = self.
entityentity.attributes.get(ATTR_DEVICE_CLASS)
543 if device_class
not in (
544 cover.CoverDeviceClass.GARAGE,
545 cover.CoverDeviceClass.GATE,
549 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
550 if supported & cover.CoverEntityFeature.SET_POSITION:
552 self.
entityentity, instance=f
"{cover.DOMAIN}.{cover.ATTR_POSITION}"
555 cover.CoverEntityFeature.CLOSE | cover.CoverEntityFeature.OPEN
558 self.
entityentity, instance=f
"{cover.DOMAIN}.{cover.ATTR_POSITION}"
560 if supported & cover.CoverEntityFeature.SET_TILT_POSITION:
563 cover.CoverEntityFeature.STOP | cover.CoverEntityFeature.STOP_TILT
570 @ENTITY_ADAPTERS.register(event.DOMAIN)
572 """Class to represent doorbel event capabilities."""
575 """Return the display categories for this entity."""
576 attrs = self.
entityentity.attributes
578 if device_class == event.EventDeviceClass.DOORBELL:
579 return [DisplayCategory.DOORBELL]
583 """Yield the supported interfaces."""
590 @ENTITY_ADAPTERS.register(light.DOMAIN)
592 """Class to represent Light capabilities."""
595 """Return the display categories for this entity."""
596 return [DisplayCategory.LIGHT]
599 """Yield the supported interfaces."""
602 color_modes = self.
entityentity.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES)
603 if light.brightness_supported(color_modes):
605 if light.color_supported(color_modes):
607 if light.color_temp_supported(color_modes):
614 @ENTITY_ADAPTERS.register(fan.DOMAIN)
616 """Class to represent Fan capabilities."""
619 """Return the display categories for this entity."""
620 return [DisplayCategory.FAN]
623 """Yield the supported interfaces."""
625 force_range_controller =
True
626 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
627 if supported & fan.FanEntityFeature.OSCILLATE:
629 self.
entityentity, instance=f
"{fan.DOMAIN}.{fan.ATTR_OSCILLATING}"
631 force_range_controller =
False
632 if supported & fan.FanEntityFeature.PRESET_MODE:
634 self.
entityentity, instance=f
"{fan.DOMAIN}.{fan.ATTR_PRESET_MODE}"
636 force_range_controller =
False
637 if supported & fan.FanEntityFeature.DIRECTION:
639 self.
entityentity, instance=f
"{fan.DOMAIN}.{fan.ATTR_DIRECTION}"
641 force_range_controller =
False
648 if force_range_controller
or supported & fan.FanEntityFeature.SET_SPEED:
650 self.
entityentity, instance=f
"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}"
657 @ENTITY_ADAPTERS.register(remote.DOMAIN)
659 """Class to represent Remote capabilities."""
662 """Return the display categories for this entity."""
663 return [DisplayCategory.REMOTE]
666 """Yield the supported interfaces."""
668 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
669 activities = self.
entityentity.attributes.get(remote.ATTR_ACTIVITY_LIST)
or []
670 if activities
and supported & remote.RemoteEntityFeature.ACTIVITY:
672 self.
entityentity, instance=f
"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}"
678 @ENTITY_ADAPTERS.register(humidifier.DOMAIN)
680 """Class to represent Humidifier capabilities."""
683 """Return the display categories for this entity."""
684 return [DisplayCategory.OTHER]
687 """Yield the supported interfaces."""
689 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
690 if supported & humidifier.HumidifierEntityFeature.MODES:
692 self.
entityentity, instance=f
"{humidifier.DOMAIN}.{humidifier.ATTR_MODE}"
695 self.
entityentity, instance=f
"{humidifier.DOMAIN}.{humidifier.ATTR_HUMIDITY}"
702 @ENTITY_ADAPTERS.register(lock.DOMAIN)
704 """Class to represent Lock capabilities."""
707 """Return the display categories for this entity."""
708 return [DisplayCategory.SMARTLOCK]
711 """Yield the supported interfaces."""
717 @ENTITY_ADAPTERS.register(media_player.const.DOMAIN)
719 """Class to represent MediaPlayer capabilities."""
722 """Return the display categories for this entity."""
723 device_class = self.
entityentity.attributes.get(ATTR_DEVICE_CLASS)
724 if device_class == media_player.MediaPlayerDeviceClass.SPEAKER:
725 return [DisplayCategory.SPEAKER]
727 return [DisplayCategory.TV]
730 """Yield the supported interfaces."""
733 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
734 if supported & media_player.MediaPlayerEntityFeature.VOLUME_SET:
736 elif supported & media_player.MediaPlayerEntityFeature.VOLUME_STEP:
739 playback_features = (
740 media_player.MediaPlayerEntityFeature.PLAY
741 | media_player.MediaPlayerEntityFeature.PAUSE
742 | media_player.MediaPlayerEntityFeature.STOP
743 | media_player.MediaPlayerEntityFeature.NEXT_TRACK
744 | media_player.MediaPlayerEntityFeature.PREVIOUS_TRACK
746 if supported & playback_features:
750 if supported & media_player.MediaPlayerEntityFeature.SEEK:
753 if supported & media_player.MediaPlayerEntityFeature.SELECT_SOURCE:
754 inputs = AlexaInputController.get_valid_inputs(
755 self.
entityentity.attributes.get(
756 media_player.const.ATTR_INPUT_SOURCE_LIST, []
762 if supported & media_player.MediaPlayerEntityFeature.PLAY_MEDIA:
768 domain = entity_info[
"domain"]
if entity_info
else None
770 supported & media_player.MediaPlayerEntityFeature.SELECT_SOUND_MODE
771 and domain !=
"denonavr"
773 inputs = AlexaEqualizerController.get_valid_inputs(
774 self.
entityentity.attributes.get(media_player.const.ATTR_SOUND_MODE_LIST)
784 @ENTITY_ADAPTERS.register(scene.DOMAIN)
786 """Class to represent Scene capabilities."""
789 """Return the Alexa API description."""
790 description = AlexaEntity.description(self)
791 if "scene" not in description.casefold():
792 return f
"{description} (Scene)"
796 """Return the display categories for this entity."""
797 return [DisplayCategory.SCENE_TRIGGER]
800 """Yield the supported interfaces."""
805 @ENTITY_ADAPTERS.register(script.DOMAIN)
807 """Class to represent Script capabilities."""
810 """Return the display categories for this entity."""
811 return [DisplayCategory.ACTIVITY_TRIGGER]
814 """Yield the supported interfaces."""
819 @ENTITY_ADAPTERS.register(sensor.DOMAIN)
821 """Class to represent Sensor capabilities."""
824 """Return the display categories for this entity."""
827 return [DisplayCategory.TEMPERATURE_SENSOR]
830 """Yield the supported interfaces."""
831 attrs = self.
entityentity.attributes
832 if attrs.get(ATTR_UNIT_OF_MEASUREMENT)
in {
833 UnitOfTemperature.FAHRENHEIT,
834 UnitOfTemperature.CELSIUS,
841 @ENTITY_ADAPTERS.register(binary_sensor.DOMAIN)
843 """Class to represent BinarySensor capabilities."""
845 TYPE_CONTACT =
"contact"
846 TYPE_MOTION =
"motion"
847 TYPE_PRESENCE =
"presence"
850 """Return the display categories for this entity."""
851 sensor_type = self.
get_typeget_type()
853 return [DisplayCategory.CONTACT_SENSOR]
855 return [DisplayCategory.MOTION_SENSOR]
857 return [DisplayCategory.CAMERA]
861 """Yield the supported interfaces."""
862 sensor_type = self.
get_typeget_type()
871 entity_conf = self.
configconfig.entity_config.get(self.
entityentity.entity_id, {})
872 if CONF_DISPLAY_CATEGORIES
in entity_conf:
873 if entity_conf[CONF_DISPLAY_CATEGORIES] == DisplayCategory.DOORBELL:
875 elif entity_conf[CONF_DISPLAY_CATEGORIES] == DisplayCategory.CONTACT_SENSOR:
877 elif entity_conf[CONF_DISPLAY_CATEGORIES] == DisplayCategory.MOTION_SENSOR:
879 elif entity_conf[CONF_DISPLAY_CATEGORIES] == DisplayCategory.CAMERA:
886 """Return the type of binary sensor."""
887 attrs = self.
entityentity.attributes
888 if attrs.get(ATTR_DEVICE_CLASS)
in (
889 binary_sensor.BinarySensorDeviceClass.DOOR,
890 binary_sensor.BinarySensorDeviceClass.GARAGE_DOOR,
891 binary_sensor.BinarySensorDeviceClass.OPENING,
892 binary_sensor.BinarySensorDeviceClass.WINDOW,
896 if attrs.get(ATTR_DEVICE_CLASS) == binary_sensor.BinarySensorDeviceClass.MOTION:
900 attrs.get(ATTR_DEVICE_CLASS)
901 == binary_sensor.BinarySensorDeviceClass.PRESENCE
908 @ENTITY_ADAPTERS.register(alarm_control_panel.DOMAIN)
910 """Class to represent Alarm capabilities."""
913 """Return the display categories for this entity."""
914 return [DisplayCategory.SECURITY_PANEL]
917 """Yield the supported interfaces."""
918 if not self.
entityentity.attributes.get(
"code_arm_required"):
924 @ENTITY_ADAPTERS.register(image_processing.DOMAIN)
926 """Class to represent image_processing capabilities."""
929 """Return the display categories for this entity."""
930 return [DisplayCategory.CAMERA]
933 """Yield the supported interfaces."""
939 @ENTITY_ADAPTERS.register(input_number.DOMAIN)
940 @ENTITY_ADAPTERS.register(number.DOMAIN)
942 """Class to represent number and input_number capabilities."""
945 """Return the display categories for this entity."""
946 return [DisplayCategory.OTHER]
949 """Yield the supported interfaces."""
950 domain = self.
entityentity.domain
956 @ENTITY_ADAPTERS.register(timer.DOMAIN)
958 """Class to represent Timer capabilities."""
961 """Return the display categories for this entity."""
962 return [DisplayCategory.OTHER]
965 """Yield the supported interfaces."""
971 @ENTITY_ADAPTERS.register(vacuum.DOMAIN)
973 """Class to represent vacuum capabilities."""
976 """Return the display categories for this entity."""
977 return [DisplayCategory.VACUUM_CLEANER]
980 """Yield the supported interfaces."""
981 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
983 (supported & vacuum.VacuumEntityFeature.TURN_ON)
984 or (supported & vacuum.VacuumEntityFeature.START)
986 (supported & vacuum.VacuumEntityFeature.TURN_OFF)
987 or (supported & vacuum.VacuumEntityFeature.RETURN_HOME)
991 if supported & vacuum.VacuumEntityFeature.FAN_SPEED:
993 self.
entityentity, instance=f
"{vacuum.DOMAIN}.{vacuum.ATTR_FAN_SPEED}"
996 if supported & vacuum.VacuumEntityFeature.PAUSE:
997 support_resume = bool(supported & vacuum.VacuumEntityFeature.START)
999 self.
entityentity, allow_remote_resume=support_resume
1006 @ENTITY_ADAPTERS.register(valve.DOMAIN)
1008 """Class to represent Valve capabilities."""
1011 """Return the display categories for this entity."""
1012 return [DisplayCategory.OTHER]
1015 """Yield the supported interfaces."""
1016 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
1017 if supported & valve.ValveEntityFeature.SET_POSITION:
1019 self.
entityentity, instance=f
"{valve.DOMAIN}.{valve.ATTR_POSITION}"
1022 valve.ValveEntityFeature.CLOSE | valve.ValveEntityFeature.OPEN
1025 if supported & valve.ValveEntityFeature.STOP:
1031 @ENTITY_ADAPTERS.register(camera.DOMAIN)
1033 """Class to represent Camera capabilities."""
1036 """Return the display categories for this entity."""
1037 return [DisplayCategory.CAMERA]
1040 """Yield the supported interfaces."""
1042 supported = self.
entityentity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
1043 if supported & camera.CameraEntityFeature.STREAM:
1050 """Check the hass URL for HTTPS scheme."""
1051 if "stream" not in self.
hasshass.config.components:
1053 "%s requires stream component for AlexaCameraStreamController",
1061 allow_internal=
False,
1064 require_standard_port=
True,
1066 except network.NoURLAvailableError:
1068 "%s requires HTTPS for AlexaCameraStreamController", self.
entity_identity_id
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Iterable[AlexaCapability] interfaces(self)
dict[str, Any] serialize_discovery(self)
list[str]|None default_display_categories(self)
None __init__(self, HomeAssistant hass, AbstractConfig config, State entity)
list[str]|None display_categories(self)
Generator[dict[str, Any]] serialize_properties(self)
list[str]|None default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
bool _check_requirements(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
list[str]|None default_display_categories(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
Generator[AlexaCapability] interfaces(self)
Generator[AlexaCapability] interfaces(self)
list[str] default_display_categories(self)
list[AlexaEntity] async_get_entities(HomeAssistant hass, AbstractConfig config)
web.Response get(self, web.Request request, str config_key)
dict[str, EntityInfo] entity_sources(HomeAssistant hass)