Si caminas por el lado luminoso de «la fuerza», te va a venir genial integrar a R2D2 en Home Assistant para que sea tu asistente.
🥑 Si estás empezando con ESPHome, te recomiendo que veas el taller de la academia para sacarle el máximo partido!
Índice
¿Quién es R2D2?
Acabo de notar como me caen piedras en la cabeza por hacer esta pregunta, pero es posible que alguien no conozca a este icónico personaje. R2D2 (o «Arturito», como se le llama cariñosamente en Latinoamérica por su pronunciación en inglés) es un droide astromecánico del universo cinematográfico de Star Wars. Habitualmente va acompañado de su amigo C3-PO y ha salvado la situación más de una vez!
Nuestro R2D2
Sé que si eres fan de Star Wars lo estabas esperando. Aunque hay muchos objetos de todo tipo en internet basados en nuestro simpático amigo, lo que hace especial al nuestro es que lo he diseñado pensando específicamente en integrar a R2D2 en Home Assistant.
Las funciones de nuestro R2D2 son las siguientes:
- R2D2 como altavoz inteligente. El modelo tiene las dimensiones perfectas para alojar en su interior tanto un Alexa Echo Dot como un Google Home Mini. Por lo tanto, tengas el que tengas, puedes «disfrazarlo» del mejor droide de la Galaxia y seguir utilizándolo como hasta ahora. Además, si has integrado Alexa o Google Assistant también vas a poder controlar tus dispositivos y emitir notificaciones.
- R2D2 como asistente local. Puesto que no es un mero objeto decorativo, también puedes utilizar a R2D2 para controlar tus dispositivos con Assist. R2D2 va a responder a tus comandos iluminando sus LED y con su sonido característico.
- Emitir notificaciones luminosas. Además los LED de R2D2 quedan expuestos como dispositivos, por lo que puedes hacerlos brillar con distintos colores y efectos cuando suceden cosas (por ejemplo, parpadear cuando acaba la lavadora, iluminarse en color rojo cuando nos estamos quedando sin batería o mostrar un efecto arcoiris cuando ha terminado nuestra impresora 3D).
- No obstante, puesto que funciona con una placa ESP lo podemos modificar para alojar los sensores que queramos e integrarlos con ESPHome.
Quiero uno!!
Si ya estás impaciente por integrar a R2D2 en Home Assistant, empezaré por decirte cómo conseguirlo:
- Constrúyelo tú mismo. Si tienes al alcance una impresora 3D puedes descargar nuestro modelo y hacerlo tú mismo. Recuerda que si eres Patreon de aguacatec tienes acceso ilimitado a todos nuestros modelos 3D, entre otras ventajas. Ten en cuenta lo siguiente a la hora de imprimir el modelo:
- Te recomiendo encarecidamente que utilices filamento transparente para imprimir las piezas que hacen de difusor. Esto hará que el efecto luminoso sea mucho más impresionante. Por cierto, para las partes de color azul he usado este filamento.
- Utiliza un ‘spray’ de pintura color plata sobre la cabeza (tapando previamente las partes azules), si quieres que tu R2D2 sea fiel al original.
- Usa pegamento de contacto para unir los adornos de color azul, el difusor LED y la cámara.
- Consíguelo con aguacoins. Si ya tienes unos cuantos aguacoins en tu monedero, puedes recibirlo en casa listo para ser montado por 4 aguacoins.
Componentes de R2D2
Antes de integrar a R2D2 en Home Assistant, repasemos los componentes necesarios:
- Primero y más importante, la estructura de nuestro R2D2.
- Una placa ESP32 S3 N16R8. Esta placa es una variación de las placas ESP32 que permiten usar MicroWakeWord.
- Un micro INMP441, para dar las órdenes a nuestro asistente.
- Un anillo de 8 LEDs WS2812B. Este es el modelo que yo he utilizado y he configurado en el código que encontrarás a continuación, pero podrías utilizar otros led direccionable que se ajusten al diseño.
- Un cable USB-C para alimentar la placa de DATOS (con un cable de carga no vas a poder instalar el software).
- Un altavoz integrado en Home Assistant para reproducir las respuestas del asistente (bien sea un altavoz local o uno de tus altavoces inteligentes). Cualquiera es buena opción mientras quepa dentro de R2D2.
💡Si vas a utilizar a R2D2 con un Google Home Mini, asegúrate de haber completado antes la integración de Google Assistant SDK. De igual manera, si lo vas a utilizar con un Alexa Echo Dot, necesitarás la integración de Alexa Media Player.
- Haber instalado ESPHome en Home Assistant.
- Haber configurado Assist en Home Assistant. Puedes usar los complementos “oficiales” de Piper (‘Text to speech’) y Whisper (‘Speech to text’) tal y como se explica en la guía enlazada. No obstante, también puedes utilizar otros complementos como el de Microsoft, para mejorar el reconocimiento de voz, o el de Eleven Labs, para escuchar voces más naturales y fluidas.
Montaje e instalación
Conexión del micro
Como siempre lo primero que te recomiendo es que consultes el ‘pinout’ (o distribución de pines) de la placa. En este caso, usaremos la ESP32 S3 N16R8 cuyo ‘pinout’ es el siguiente.
Empezaremos por soldar directamente el micro a nuestra placa, con el siguiente esquema de conexión.
- SCK (verde) irá conectado al pin GPIO2 de la placa.
- WS (naranja) irá conectado al pin GPIO3 de la placa.
- SD (amarillo) irá conectado al pin GPIO4 de la placa.
- L/R (blanco) y GND (negro) irán conectados al pin GND (‘ground’ o tierra) de la placa.
- VDD (rojo) irá conectado al pin de alimentación 3v3 de la placa
Intenta no recortar mucho los cables, ya que te va a venir bien aprovechar toda la longitud que te ofrecen para colocar los componentes dentro de la cabeza de R2D2.
Conexión del Anillo LED
Como cualquier tira LED WS2812B nuestro anillo tiene los siguientes pines, que también vamos a soldar directamene a la placa (por lo que tendrás que cortar el adaptador que trae en el extremo de los cables de entrada, a la izquierda).
- El cable rojo proporciona la alimentación a 5 voltios, por lo que irá al pin correspondiente (5V)
- El cable blanco es el de la conexión de tierra o ‘ground’, e irá conectado a dicho pin (GND)
- El cable verde proporciona los datos e irá conectado al GPIO9.
- Te recomiendo que cortes los cables de salida (a la derecha, identificados con la leyenda ‘DO’ de ‘data output’), ya que no los vamos a utilizar. También cortar las pequeñas pestañitas de cartón que suelen tener estos anillos en el interior, para que encaje bien en su pieza.
- Adicionalmente, en la placa tendrás que aplicar una pequeña soldadura para unir los circuitos indicados como ‘RGB‘ (para mandar la información al anillo LED) y ‘IN-OUT‘ (para habilitar la salida de 5V). Si te fijas de cerca, tienen una pequeña endidura que impide el contacto del circuito. Te he marcado la situación de ambos con un círculo rojo en la imagen del ‘pinout’ que he incluido más arriba. Si no ves alguno de estos puentes, es que ya viene hecho internamente.
Montaje de R2D2
Ya tenemos los componentes electrónicos, ahora vamos a preparar a nuestro amigo. Para ello te recomiendo que sigas estos pasos:
- Tapa bien con cinta de carrocero las partes azules de la cabeza de R2D2. Puedes ayudarte de un bisturí o cutter para ajustar bien la cinta a los espacios. Después utiliza un ‘spray’ de color plata para pintar las partes descubiertas. Deja secar bien y retira la cinta de para descubrir el resultado. Si en algún sitio se ha colado pintura de más, puedes utilizar un bastoncillo y mojarlo un poco en líquido «limpia uñas».
- Utiliza pegamento de contacto para pegar la cámara en el orificio, y el difusor LED desde el interior de la cabeza.
- Ha llegado el momento de colocar los componentes electrónicos. Puedes utilizar una pistola de silicona para fijarlos al casco. Básicamente tienes que atender a dos cosas. La primera es que el micrófono quede bien centrado en el orificio superior, y la segunda que haya algún LED apuntando directamente al orificio correspondiente.
- El resto es pan comido, sólo tienes que utilizar pegamento de contacto para pegar los adornos azules en el cuerpo y colocar cada parte en su sitio. No te olvides de colocar dentro tu altavoz y de pasar los cables por los orificios de la parte posterior.
Respecto a la configuración de la placa, no hay problema ya que vas a poder acceder a los puertos USB-C desde la parte trasera o levantando la cabeza.
Ficheros de audio
Antes de integrar a R2D2 en Home Assistant vamos a cargar en nuestra instancia 3 ficheros de audio que contienen el sonido característico de R2D2, y que se van a corresponder con el inicio y fin de nuestros comandos de voz, así como cuando se produce un error en la orden. Para ello te recomiendo que utilices el complemento Samba Share y tu explorador de archivos.
Lo primero que tienes que hacer es hacer clic en este enlace para descargar los ficheros correspondientes. Ahora tienes que subirlo a una ruta, que va a depender del altavoz que vayas a utilizar.
- Si utilizas un Google Home Mini o un altavoz local, sube los ficheros dentro de la carpeta ‘/media/Asistente/’ (la carpeta «Asistente» no existe por defecto, por lo que tendrás que crearla).
- Si utilizas Alexa con un Echo Dot, sube los ficheros dentro de la carpeta ‘config/www/Asistente/’ (la carpeta «Asistente» no existe por defecto, por lo que tendrás que crearla).
Configuración de ESPHome
Ya tenemos listos los componentes que necesitamos para integrar a R2D2 en Home Assistant. Ahora tenemos que ‘flashear’ la placa con ESPHome y la configuración correspondiente. Para ello sigue estos pasos:
- Conecta la placa a tu ordenador a través del puerto USB-C.
- En Home Assistant, accede al complemento de ESPHome desde el menú lateral y pulsa en «New device». Pulsa en «Continue» y dale un nombre (por ejemplo, «R2D2»).
- Pulsa en «Next» y a continuación selecciona la opción «ESP32-S3» como tipo de dispositivo. Verás que en el fondo se ha creado un nuevo dispositivo.
- Pulsa en «Skip» y haz clic en el enlace «Edit» del bloque correspondiente al dispositivo que acabas de crear.
- Si utilizas Google Home Mini o un altavoz local, reemplaza el código por defecto con el siguiente, haciendo los siguientes cambios:
- Ajusta el ‘name’ y ‘friendly-name’ como el nombre que le quieras dar a tu asistente (por ejemplo, «R2D2»).
- Añade la información que te había generado el complemento en el apartado ‘api’ (‘encryption key’). Haz lo mismo para el campo ‘password’ bajo el apartado ‘ota’, y para los campos ‘ssid’ y ‘password’ bajo el apartado ‘ap’.
- Si por algún motivo hubieras utilizado pines diferentes en el cableado de los componentes, ajusta la distribución de los pines el código. En caso contrario no debes preocuparte por ello.
- Revisa el apartado del componente ‘light’. Verás que he creado dos segmentos partiendo del anillo LED, con el objetivo de poder mostrar un efecto diferente en cada uno de los LED de la cabeza de R2D2. Por defecto he asignado que el pequeño use el LED nº7 del anillo, y el grande los nº4 y 5. Esto va a depender de la posición en la que hayas pegado el anillo LED, pero si cuando lo enciendas no coincide, después lo puedes adaptar sin problema (teniendo en cuenta que los LED van del 0 al 7 en este caso).
- Modifica la ruta de los ficheros de audio para que apunte a los ficheros que has cargado en el apartado anterior (por ejemplo, «media-source://media_source/local/Asistente/r2d2-start.mp3»).
- Modifica el nombre de la entidad correspondiente a tu altavoz (por ejemplo, «media_player.DISPOSITIVO»).
- Al final del código, indica la entidad del servicio ‘text-to-speech’ (o ‘tts’) que quieres utilizar en las respuestas del asistente. En mi caso voy a utilizar la integración de ElevenLabs, ya que me gusta las voces naturales y fluidas que tiene.
esphome: name: aguacatec-assistant friendly_name: Aguacatec Assistant platformio_options: board_build.flash_mode: dio on_boot: - light.turn_on: id: led_ring effect: "Pulse" brightness: 80% red: 100% green: 0% blue: 0% - delay: 2s - light.turn_off: id: led_ring esp32: board: esp32-s3-devkitc-1 framework: type: esp-idf sdkconfig_options: CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y" CONFIG_ESP32S3_DATA_CACHE_64KB: "y" CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y" CONFIG_AUDIO_BOARD_CUSTOM: "y" psram: mode: octal # Please change this to quad for N8R2 and octal for N16R8 speed: 80MHz # Enable Home Assistant API api: encryption: key: "zf456asdsasadasdDXj/F8vvo456645ujPXo=" on_client_connected: then: - delay: 50ms - micro_wake_word.start: on_client_disconnected: then: - voice_assistant.stop: logger: ota: - platform: esphome password: "3632453434537acdfsgdf11d1" wifi: ssid: !secret wifi_ssid password: !secret wifi_password power_save_mode: none # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "Aguacatec-Assistant" password: "9k23423PUNbdsffsd" captive_portal: light: - platform: partition name: "Small LED" id: small_led effects: - strobe: name: "Strobe r2d2" colors: - state: true brightness: 100% red: 100% green: 0% blue: 0% duration: 1s - state: true brightness: 80% red: 100% green: 100% blue: 100% duration: 0.5s segments: - id: led_ring from: 7 to: 7 - platform: partition name: "Big LED" id: big_led segments: - id: led_ring from: 4 to: 5 - platform: esp32_rmt_led_strip id: led_ring internal: true rgb_order: GRB pin: GPIO09 num_leds: 8 rmt_channel: 1 chipset: ws2812 name: "Led Ring" effects: - pulse: # Audio and Voice Assistant Config i2s_audio: - id: i2s_in # For microphone i2s_lrclk_pin: GPIO3 #WS i2s_bclk_pin: GPIO2 #SCK microphone: - platform: i2s_audio id: va_mic adc_type: external i2s_din_pin: GPIO4 #SD channel: left pdm: false i2s_audio_id: i2s_in bits_per_sample: 32bit micro_wake_word: on_wake_word_detected: - homeassistant.service: service: media_player.play_media data: entity_id: media_player.DISPOSITIVO media_content_id: media-source://media_source/local/Asistente/r2d2-start.mp3 media_content_type: audio/mpeg - light.turn_on: id: small_led effect: "Strobe r2d2" - delay: 1s - light.turn_on: id: big_led red: 0% green: 0% blue: 100% brightness: 100% - delay: 3s - voice_assistant.start: wake_word: !lambda return wake_word; silence_detection: true models: hey_jarvis voice_assistant: id: va microphone: va_mic auto_gain: 31dBFS noise_suppression_level: 2 volume_multiplier: 4.0 on_stt_end: then: - light.turn_off: small_led - light.turn_off: big_led on_error: then: - homeassistant.service: service: media_player.play_media data: entity_id: media_player.DISPOSITIVO media_content_id: media-source://media_source/local/Asistente/r2d2-error.mp3 media_content_type: audio/mpeg - light.turn_on: id: big_led red: 100% green: 0% blue: 0% brightness: 100% - delay: 2s - light.turn_off: big_led - wait_until: not: voice_assistant.is_running: - micro_wake_word.start: on_end: then: - homeassistant.service: service: media_player.play_media data: entity_id: media_player.DISPOSITIVO media_content_id: media-source://media_source/local/Asistente/r2d2-end.mp3 media_content_type: audio/mpeg - light.turn_on: id: small_led effect: "Strobe r2d2" - light.turn_on: id: big_led red: 0% green: 100% blue: 0% brightness: 100% - delay: 5s - light.turn_off: small_led - light.turn_off: big_led - wait_until: not: voice_assistant.is_running: - micro_wake_word.start: on_tts_start: - light.turn_on: id: small_led effect: "Strobe r2d2" - light.turn_on: id: big_led red: 0% green: 100% blue: 0% brightness: 100% - homeassistant.service: service: tts.speak data: media_player_entity_id: media_player.DISPOSITIVO message: !lambda 'return x;' entity_id: tts.elevenlabs_tts - light.turn_off: small_led - light.turn_off: big_led
- Si utilizas Alexa con un Echo Dot, reemplaza el código por defecto con el siguiente, haciendo los siguientes cambios:
- Ajusta el ‘name’ y ‘friendly-name’ como el nombre que le quieras dar a tu asistente (por ejemplo, «R2D2»).
- Añade la información que te había generado el complemento en el apartado ‘api’ (‘encryption key’). Haz lo mismo para el campo ‘password’ bajo el apartado ‘ota’, y para los campos ‘ssid’ y ‘password’ bajo el apartado ‘ap’.
- Si por algún motivo hubieras utilizado pines diferentes en el cableado de los componentes, ajusta la distribución de los pines el código. En caso contrario no debes preocuparte por ello.
- Revisa el apartado del componente ‘light’. Verás que he creado dos segmentos partiendo del anillo LED, con el objetivo de poder mostrar un efecto diferente en cada uno de los LED de la cabeza de R2D2. Por defecto he asignado que el pequeño use el LED nº7 del anillo, y el grande los nº4 y 5. Esto va a depender de la posición en la que hayas pegado el anillo LED, pero si cuando lo enciendas no coincide, después lo puedes adaptar sin problema (teniendo en cuenta que los LED van del 0 al 7 en este caso).
- Modifica la ruta de los ficheros de audio para que apunte a los ficheros que has cargado en el apartado anterior (por ejemplo, «https://tudominio.com/local/Asistente/r2d2-start.mp3»).
- Modifica el nombre de la entidad correspondiente a tu Echo Dot (por ejemplo, «media_player.echo_dot_DISPOSITIVO»).
esphome: name: aguacatec-assistant friendly_name: Aguacatec Assistant platformio_options: board_build.flash_mode: dio on_boot: - light.turn_on: id: led_ring effect: "Pulse" brightness: 80% red: 100% green: 0% blue: 0% - delay: 2s - light.turn_off: id: led_ring esp32: board: esp32-s3-devkitc-1 framework: type: esp-idf sdkconfig_options: CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y" CONFIG_ESP32S3_DATA_CACHE_64KB: "y" CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y" CONFIG_AUDIO_BOARD_CUSTOM: "y" psram: mode: octal # Please change this to quad for N8R2 and octal for N16R8 speed: 80MHz # Enable Home Assistant API api: encryption: key: "zfsYMSIhdshdfshfd99JpP3zDXj/377474742´2=" on_client_connected: then: - delay: 50ms - micro_wake_word.start: on_client_disconnected: then: - voice_assistant.stop: logger: ota: - platform: esphome password: "36ajhbsd87238797ba37acf234324fsd1d1" wifi: ssid: !secret wifi_ssid password: !secret wifi_password power_save_mode: none # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "Aguacatec-Assistant" password: "9kFnasdfsadf848" captive_portal: light: - platform: partition name: "Small LED" id: small_led effects: - strobe: name: "Strobe r2d2" colors: - state: true brightness: 100% red: 100% green: 0% blue: 0% duration: 1s - state: true brightness: 80% red: 100% green: 100% blue: 100% duration: 0.5s segments: - id: led_ring from: 7 to: 7 - platform: partition name: "Big LED" id: big_led segments: - id: led_ring from: 4 to: 5 - platform: esp32_rmt_led_strip id: led_ring internal: true rgb_order: GRB pin: GPIO09 num_leds: 8 rmt_channel: 1 chipset: ws2812 name: "Led Ring" effects: - pulse: # Audio and Voice Assistant Config i2s_audio: - id: i2s_in # For microphone i2s_lrclk_pin: GPIO3 #WS i2s_bclk_pin: GPIO2 #SCK microphone: - platform: i2s_audio id: va_mic adc_type: external i2s_din_pin: GPIO4 #SD channel: left pdm: false i2s_audio_id: i2s_in bits_per_sample: 32bit micro_wake_word: on_wake_word_detected: - homeassistant.service: service: notify.alexa_media data: message: "<audio src='https://tudominio.com/local/Asistente/r2d2-start.mp3'/>" target: media_player.echo_dot_DISPOSITIVO - light.turn_on: id: small_led effect: "Strobe r2d2" - delay: 1s - light.turn_on: id: big_led red: 0% green: 0% blue: 100% brightness: 100% - delay: 3s - voice_assistant.start: wake_word: !lambda return wake_word; silence_detection: true model: hey_jarvis voice_assistant: id: va microphone: va_mic auto_gain: 31dBFS noise_suppression_level: 2 volume_multiplier: 4.0 on_stt_end: then: - light.turn_off: small_led - light.turn_off: big_led on_error: then: - homeassistant.service: service: notify.alexa_media data: message: "<audio src='https://tudominio.com/local/Asistente/r2d2-error.mp3'/>" target: media_player.echo_dot_DISPOSITIVO - light.turn_on: id: big_led red: 100% green: 0% blue: 0% brightness: 100% - delay: 2s - light.turn_off: big_led - wait_until: not: voice_assistant.is_running: - micro_wake_word.start: on_end: then: - homeassistant.service: service: notify.alexa_media data: message: "<audio src='https://tudominio.com/local/Asistente/r2d2-end.mp3'/>" target: media_player.echo_dot_DISPOSITIVO - light.turn_on: id: small_led effect: "Strobe r2d2" - light.turn_on: id: big_led red: 0% green: 100% blue: 0% brightness: 100% - delay: 5s - light.turn_off: small_led - light.turn_off: big_led - wait_until: not: voice_assistant.is_running: - micro_wake_word.start: on_tts_start: - light.turn_on: id: small_led effect: "Strobe r2d2" - light.turn_on: id: big_led red: 0% green: 100% blue: 0% brightness: 100% - homeassistant.service: service: notify.alexa_media_echo_dot_DISPOSITIVO data: message: !lambda 'return x;' - light.turn_off: small_led - light.turn_off: big_led
- Cuando hayas terminado de editar el código pulsa en «Save» e «Install». Selecciona la opción «Manual download» y espera a que el código se compile (ten paciencia, que tarda un ratillo).
- Cuando termine, selecciona la opción «Modern format» para descargar el fichero ‘.bin’ correspondiente.
- Ahora ve a la página de ESPHome y pulsa en «Connect». En la ventana emergente selecciona tu placa y pulsa en «Conectar».
- Ahora pulsa en «Install» y selecciona el fichero ‘.bin’ obtenido en el paso 8. De nuevo, pulsa en «Install».
⚠️ Si se genera un error en la instalación, inténtalo de nuevo mientras pulsas un pequeño botón que hay en la placa que indica 'boot' hasta que comience la instalación. Como alternativa, desconecta el cable USB-C y conéctalo al otro puerto de la placa. Si aun así el error permanece es probable que necesites instalar los 'drivers' para placas ESP.
- Vuelve a Home Assistant y ve a Ajustes > Dispositivos y servicios. Lo normal es que tu dispositivo haya sido descubierto y aparezca en la parte superior, esperando únicamente a que pulses el botón de «Configurar». De lo contrario pulsa en el botón de «Añadir integración», busca «ESPHome» e introduce la IP de tu placa en el campo ‘Host’.
- Al añadir tu dispositivo ya aparecerá dentro del bloque de «ESPHome» entre tus integraciones. Accede al dispositivo y selecciona:
- Detección de fin de habla. Selecciona la opción «agresivo».
- Tubería de Assist. Selecciona el ‘pipeline’ que hayas configurado para tu asistente. Por cierto, también tienes que acceder a Ajustes > Asistentes de voz, pulsar sobre tu ‘pipeline’ y bajar hasta el apartado de «Palabra de activación» para dejarlo vacío (ya que, como hemos visto, vamos a utilizar el componente MicroWakeWord desde el propio dispositivo).
🥑 Mis opciones favoritas son la de Microsoft para el componente STT y ElevenLabs para el componente TTS. Con esta combinación, junto a la MicroWakeWord he conseguido un rendimiento muy bueno!
- Para terminar ve a Ajustes > Dispositivos y servicios > ESPHome. Pulsa sobre el enlace «Configurar» correspondiente al dispositivo de tu asistente. En la ventana emergente marca la casilla «Permitir que el dispositivo realice llamadas de servicio de Home Assistant» y pulsa en «Enviar». Esto va a permitir que el asistente emita el audio por otros altavoces.
🥑 Si estás configurando Assist, te recomiendo que veas el taller de la academia para sacarle el máximo partido!