Cómo mostrar paneles de Home Assistant en dispositivos Echo Show con Alexa
Los dispositivos Amazon Echo Show ofrecen una excelente oportunidad para visualizar y controlar paneles de Home Assistant mediante comandos de voz. Esta guía técnica detalla el proceso actualizado para crear una Alexa Skill personalizada que permite mostrar tableros de Home Assistant en cualquier dispositivo Echo Show.
Requisitos previos
Antes de comenzar, asegúrate de contar con:
- Una instalación funcional de Home Assistant con acceso mediante URL o dirección IP
- Un dispositivo Amazon Echo Show configurado
- Una cuenta de Amazon Developer (puede ser la misma cuenta de tu Echo Show)
- Acceso a la consola de administración de Home Assistant
Paso 1: Creación del panel en Home Assistant
El primer paso consiste en crear el panel o tablero que deseas visualizar en tu Echo Show. Este proceso requiere atención especial en la configuración de la URL.
Crear el tablero
Accede a Configuración > Tableros > Agregar tablero. Selecciona la opción de crear un panel desde cero para tener control total sobre su personalización. Asigna un nombre descriptivo, por ejemplo “Echo Show”.
Configurar la URL del panel
Este es un paso crítico. Una vez creado el tablero, edítalo haciendo clic en el icono de lápiz en la esquina superior derecha. Localiza la sección “Vista sin nombre” y haz clic en el lápiz para editarla.
En el campo URL, debes ingresar una nomenclatura específica: una letra seguida de un número. Por ejemplo: P1 (Panel 1). Home Assistant no permite usar solo números como URL, por eso es necesario anteponer una letra.
Si planeas crear múltiples paneles, mantén la misma letra y cambia solo el número: P1, P2, P3, etc. Esta nomenclatura es fundamental porque posteriormente permitirá invocar los paneles mediante comandos de voz como “mostrar panel 1” o “mostrar panel 2”.
Personalizar el contenido
Agrega los dispositivos, sensores y controles que deseas visualizar en el Echo Show. Puedes incluir luces con control de brillo, interruptores, sensores de temperatura, cámaras o cualquier entidad disponible en tu instalación de Home Assistant.
Paso 2: Acceder a Alexa Developer Console
Es fundamental iniciar sesión en la consola de desarrollador de Alexa con la misma cuenta de Amazon vinculada a tu dispositivo Echo Show. Si utilizas una cuenta diferente, la Skill no será visible en tu dispositivo.
Abre una nueva pestaña del navegador y accede a la Alexa Developer Console. Una vez dentro, verás la interfaz para crear y gestionar Skills personalizadas.
https://developer.amazon.com/alexa/console/ask
Paso 3: Crear una nueva Alexa Skill
Configuración inicial
Haz clic en Create Skill y proporciona la siguiente información:
- Nombre: Puedes usar un nombre descriptivo como “Dashboard Viewer” o “Visor de Tablero”
- Idioma: Selecciona el idioma en el que interactuarás con Alexa. Es crucial que coincida exactamente con el idioma configurado en tu Echo Show (español de España, español de México o español de Estados Unidos)
Selección del modelo
En la siguiente pantalla, selecciona:
- Tipo: Other
- Modelo: Custom
- Hosting Services: Alexa Hosted (Python)
- Región: Selecciona la región más cercana a tu ubicación geográfica (por ejemplo, US East para América)
Continúa seleccionando Start from scratch y confirma la creación. El proceso tardará entre 2 y 3 minutos.
Paso 4: Configurar el nombre de invocación
Una vez creada la Skill, cierra el tutorial emergente y dirígete a Invocations > Skill Invocation Name.
Aquí defines la frase que usarás para activar la Skill. Puedes usar expresiones como:
- “visor de tablero”
- “visor de panel”
- “panel de la casa”
Esta frase será parte del comando completo, por ejemplo: “Alexa, dile a visor de tablero que abra panel 1”.
Guarda los cambios haciendo clic en Save.
Paso 5: Crear el Intent personalizado
Eliminar el Intent predeterminado
En el menú lateral, accede a Interaction Model > Intents. Elimina el Intent “Hello World” que viene por defecto, ya que no lo necesitarás.
Crear el nuevo Intent
Haz clic en Add Intent, selecciona “Create Custom Intent” y nómbralo OpenPageIntent.
Configurar el Slot
Desplázate hasta la sección Intent Slots y configura:
- Nombre del Slot: Page
- Tipo: AMAZON.NUMBER
Este Slot capturará el número del panel que deseas abrir.
Definir Sample Utterances
En la sección Sample Utterances, agrega la frase que usarás para invocar el panel:
Mostrar Panel {page}
Las llaves indican que “Page” es una variable que será reemplazada por el número que digas. Haz clic en el símbolo “+” para agregar la frase y guarda los cambios.
Paso 6: Habilitar Alexa Presentation Language
En el menú lateral, accede a Interfaces y habilita Alexa Presentation Language. Esta interfaz es esencial para mostrar contenido visual en dispositivos con pantalla como el Echo Show.
Guarda los cambios.
Paso 7: Compilar el modelo de interacción
Regresa a Interaction Model > Intents y haz clic en el botón Build Skill ubicado en la esquina superior derecha. Este proceso compilará toda la configuración y tardará entre 1 y 2 minutos.
Paso 8: Configurar el código Lambda
Una vez finalizada la compilación, dirígete a la pestaña Code en el menú superior.
Modificar lambda_function.py
Elimina todo el código existente en el archivo lambda_function.py y reemplázalo con el código personalizado para Home Assistant.
import json
import logging
import ask_sdk_core.utils as ask_utils
from ask_sdk_core.skill_builder import SkillBuilder
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.dispatch_components import AbstractExceptionHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model.interfaces.alexa.presentation.apl import RenderDocumentDirective, ExecuteCommandsDirective, OpenUrlCommand
from ask_sdk_model import Response
from typing import Dict, Any
#################### Change this ########################
DASHBOARD_URL = "http://192.168.1.132:8123/echo-show/"
KIOSK_MODE = False
#########################################################
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
TOKEN = "someToken"
def open_page(number):
page = "p" + str(number) if number != "" else ""
if KIOSK_MODE:
source = DASHBOARD_URL + page + "?kiosk"
else:
source = DASHBOARD_URL + page
return OpenUrlCommand(
source = source
)
def _load_apl_document(file_path):
# type: (str) -> Dict[str, Any]
"""Load the apl json document at the path into a dict object."""
with open(file_path) as f:
return json.load(f)
class LaunchRequestHandler(AbstractRequestHandler):
"""Handler for Skill Launch."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return ask_utils.is_request_type("LaunchRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
response_builder = handler_input.response_builder
# Render empty template, needed for OpenURL command
# see https://amazon.developer.forums.answerhub.com/questions/220506/alexa-open-a-browser.html
response_builder.add_directive(
RenderDocumentDirective(
token=TOKEN,
document=_load_apl_document("template.json")
)
)
# Open default page of dashboard
response_builder.add_directive(
ExecuteCommandsDirective(
token=TOKEN,
commands=[open_page("")]
)
)
return response_builder.response
class OpenPageIntentHandler(AbstractRequestHandler):
"""Handler for Open Page Intent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return ask_utils.is_intent_name("OpenPageIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
response_builder = handler_input.response_builder
number = ask_utils.request_util.get_slot(handler_input, "page").value
# Render empty template, needed for OpenURL command
# see https://amazon.developer.forums.answerhub.com/questions/220506/alexa-open-a-browser.html
response_builder.add_directive(
RenderDocumentDirective(
token=TOKEN,
document=_load_apl_document("template.json")
)
)
# Open respective page of dashboard
response_builder.add_directive(
ExecuteCommandsDirective(
token=TOKEN,
commands=[open_page(number)]
)
)
return response_builder.response
class HelpIntentHandler(AbstractRequestHandler):
"""Handler for Help Intent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return ask_utils.is_intent_name("AMAZON.HelpIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
return (
handler_input.response_builder
.response
)
class CancelOrStopIntentHandler(AbstractRequestHandler):
"""Single handler for Cancel and Stop Intent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return (ask_utils.is_intent_name("AMAZON.CancelIntent")(handler_input) or
ask_utils.is_intent_name("AMAZON.StopIntent")(handler_input))
def handle(self, handler_input):
# type: (HandlerInput) -> Response
return (
handler_input.response_builder
.response
)
class SessionEndedRequestHandler(AbstractRequestHandler):
"""Handler for Session End."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return ask_utils.is_request_type("SessionEndedRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
# Any cleanup logic goes here.
return handler_input.response_builder.response
class IntentReflectorHandler(AbstractRequestHandler):
"""The intent reflector is used for interaction model testing and debugging.
It will simply repeat the intent the user said. You can create custom handlers
for your intents by defining them above, then also adding them to the request
handler chain below.
"""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return ask_utils.is_request_type("IntentRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
intent_name = ask_utils.get_intent_name(handler_input)
speak_output = "You just triggered " + intent_name + "."
return (
handler_input.response_builder
.speak(speak_output)
# .ask("add a reprompt if you want to keep the session open for the user to respond")
.response
)
class CatchAllExceptionHandler(AbstractExceptionHandler):
"""Generic error handling to capture any syntax or routing errors. If you receive an error
stating the request handler chain is not found, you have not implemented a handler for
the intent being invoked or included it in the skill builder below.
"""
def can_handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> bool
return True
def handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> Response
logger.error(exception, exc_info=True)
speak_output = "An error has occured."
return (
handler_input.response_builder
.speak(speak_output)
.response
)
# The SkillBuilder object acts as the entry point for your skill, routing all request and response
# payloads to the handlers above. Make sure any new handlers or interceptors you've
# defined are included below. The order matters - they're processed top to bottom.
sb = SkillBuilder()
sb.add_request_handler(LaunchRequestHandler())
sb.add_request_handler(OpenPageIntentHandler())
sb.add_request_handler(HelpIntentHandler())
sb.add_request_handler(CancelOrStopIntentHandler())
sb.add_request_handler(SessionEndedRequestHandler())
sb.add_request_handler(IntentReflectorHandler()) # make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers
sb.add_exception_handler(CatchAllExceptionHandler())
lambda_handler = sb.lambda_handler()
El elemento más importante a modificar en este código es la URL de acceso a tu Home Assistant. Debes cambiar la dirección IP o URL por la de tu instalación, seguida del nombre del panel que creaste. Por ejemplo:
http://192.168.1.100:8123/echo-show
Si utilizaste una letra diferente a “p” para nombrar tus paneles en el Paso 1, debes modificar también la línea 24 del código, donde se construye la variable “page”. Cambia la “P” por la letra que hayas elegido.
Guarda los cambios haciendo clic en Save.
Crear el archivo template.json
En el panel izquierdo, haz clic derecho sobre la carpeta lambda y selecciona Create file. Nombra el archivo exactamente como:
template.json
Pega el código JSON correspondiente en este archivo y guarda los cambios.
{
"type": "APL",
"version": "1.6",
"description": "Empty APL document.",
"settings": {},
"theme": "dark",
"import": [],
"resources": [],
"styles": {},
"onMount": [],
"graphics": {},
"commands": {},
"layouts": {},
"mainTemplate": {
"items": [
{
"type": "Text",
"height": "100vh",
"textAlign": "center",
"textAlignVertical": "center",
"text": ""
}
]
}
}
Desplegar el código
Haz clic en el botón Deploy para desplegar el código en el entorno de Alexa. Este proceso tardará unos segundos.
Paso 9: Probar la Skill
Accede a la pestaña Test en el menú superior. Cambia el estado de “Test is disabled for this skill” a Development.
El navegador puede solicitar permiso para acceder al micrófono. Concede el permiso para realizar pruebas por voz, aunque también puedes escribir los comandos manualmente.
Prueba el comando completo:
Dile a visor de tablero que abra panel 1
Si todo está configurado correctamente, se abrirá una ventana mostrando el panel de Home Assistant.
Paso 10: Usar la Skill en el Echo Show
Una vez verificado que la Skill funciona en el entorno de pruebas, puedes invocarla directamente en tu Echo Show:
Alexa, dile a visor de tablero que abra panel 1
La primera vez que ejecutes el comando, el navegador Silk del Echo Show solicitará las credenciales de Home Assistant. Ingresa tu usuario y contraseña. Las credenciales quedarán guardadas para futuros accesos.
Solución de problemas comunes
Alexa no encuentra la Skill
El problema más frecuente es la discrepancia entre el idioma configurado en la Skill y el idioma del dispositivo Echo Show. Verifica que ambos coincidan exactamente, incluyendo la variante regional (España, México, Estados Unidos).
Para verificar esto:
- En la Developer Console, accede a la Skill y revisa la sección Languages
- En la aplicación móvil de Alexa, verifica el idioma configurado en tu Echo Show
- Agrega el idioma exacto a tu Skill si no está presente
El panel no se muestra correctamente
Verifica que:
- La URL de Home Assistant sea accesible desde internet o desde la red local donde está el Echo Show
- El nombre del panel en la URL coincida exactamente con el configurado en Home Assistant
- La interfaz Alexa Presentation Language esté habilitada
Error de autenticación
Si el Echo Show solicita credenciales repetidamente, puede deberse a que las cookies del navegador Silk se están eliminando. Asegúrate de que el Echo Show no tenga configurada la eliminación automática de datos de navegación.
Crear múltiples paneles
Para agregar más paneles, simplemente:
- Crea nuevos tableros en Home Assistant con URLs P2, P3, P4, etc.
- No necesitas modificar la Skill, ya que el código está preparado para manejar cualquier número
- Invoca los paneles adicionales con comandos como “Alexa, dile a visor de tablero que abra panel 2”
Consideraciones de seguridad
Ten en cuenta que este método expone tu interfaz de Home Assistant a través del navegador del Echo Show. Algunas recomendaciones:
- Utiliza contraseñas seguras para tu instalación de Home Assistant
- Considera crear un usuario específico con permisos limitados solo para visualización
- Si expones Home Assistant a internet, implementa medidas de seguridad adicionales como certificados SSL y autenticación de dos factores
- Revisa periódicamente los logs de acceso de Home Assistant
Optimización de paneles para Echo Show
Los dispositivos Echo Show tienen pantallas de diferentes tamaños según el modelo. Para una mejor experiencia:
- Utiliza tarjetas grandes y legibles
- Limita la cantidad de información en cada panel
- Prueba la visualización en el dispositivo real antes de finalizar el diseño
- Considera crear paneles específicos para cada habitación o función