De vez en cuando, cuando estoy en frente de la computadora en el escritorio, necesito saber cuál es la hora. Por supuesto, siempre puedo mirar a las esquinas inferiores de los monitores (Windows 11) para obtener la información, pero no con poca frecuencia tengo demasiadas cosas encima de la mesa que me dificultan la visibilidad de la zona más inferior de las pantallas. Aparte, mientras estoy jugando algo, generalmente a pantalla completa, el reloj del monitor principal desaparece y debo girar la cabeza para verificar la hora. Es el problema más intrascendente de la historia pero sentía que necesitaba un reloj dedicado para resolverlo.

Es una idea que lleva en mi mente unos meses, quizás más de un año. Como siempre, me demoro en resolver las cosas que me causan molestias si no es urgente, así que lo más fácil era esperar a que la solución, o algo que se le parezca, llegue a mí.

Y sucedió. No recuerdo cómo, no recuerdo cuándo, no recuerdo dónde pero me enteré de la existencia del Vobot Mini Dock, que es una especie de reloj de escritorio conectado a internet que funciona como hub USB y con algunas aplicaciones que podrían servirle a alguien. Lo que más me llamó la atención fue que el producto permitía aplicaciones desarrolladas por terceros y hasta tenían una pequeña tienda para encontrar nuevas. Lo compré.

Puede emular algunos juegos también (imagen oficial de Vobot)
Puede emular algunos juegos también (imagen oficial de Vobot)

Interesante dispositivo.

Al conectarlo y probarlo por primera vez resultó aparente el uso principal que le quería dar. Necesitaba de él un servicio similar al que ofrecía el Spotify Car Thing (captura de Archive.org ya que la página original ya no existe) en sus buenos días antes de morir.

Obviamente, no podía pedirle demasiado. Está basado en el ESP32S3, que es un microcontrolador con 512 KB de RAM y un CPU a 240 MHz (para referencia, un Samsung Galaxy S25 tiene 12 GB de RAM y un procesador con núcleos que pueden alcanzar los 4.47 GHz) y tiene una pantalla LCD de 240x320 píxeles; o sea, bastante básico pero seguramente suficiente. Sólo necesitaba que me dijera qué canción se estaba reproduciendo en ese momento, el artista y, con un poco de suerte, que me muestre la portada del álbum al cual pertenece la canción en cuestión.

Busqué en la tienda de aplicaciones alguna app que ofreciera algo parecido pero no tuve suerte, la oferta es más bien pobre y sólo hay una aplicación de un tercero aparte de las aproximadamente 10 que ofrece la propia Vobot.

Era momento de llevar mi visión a la realidad yo mismo.

El problema

No tenía idea de qué lenguaje usaba Vobot para las aplicaciones del Mini Dock, pero seguramente C++ o alguna variante. Pues no, usa MicroPython para la lógica y LVGL para los gráficos. Experiencia con Python tengo, así que programar en su versión para microcontroladores debería ser similar, pero jamás había siquiera oído de LVGL; obviamente, tenía que leer toda la documentación que pudiera para aprender a usarlo.

La documentación de LVGl para C es bastante completa pero para MicroPython es, digamos, un poco optimista por no decir incompleta. No pude aprender demasiado leyendo la referencia de la API; además, los nombres de métodos son bastante parecidos entre uno y otro lenguaje pero el patrón no es totalmente evidente a primera vista. Menos mal tuve ayuda de un par de proyectos preexistentes precisamente para este relojito. Gracias a @itandy848 y su repo HK Weather y a la misma Vobot pude reconstruir las partes del código con las que la documentación oficial no me ayudó mucho.

Ah, por cierto, la documentación de Vobot para el desarrollo de aplicaciones es prácticamente inexistente. De no haber hecho público el código para algunas de sus aplicaciones pre-instaladas no estaría escribiendo este artículo o habría sido publicado 9 meses más tarde como mínimo.

Bien, con todas (o casi todas) las piezas en su lugar, finalmente podía dedicarme a escribir el código.

La idea es simple:

  • Realizar el proceso de autenticación para que Spotify supiera quién está consumiendo su API
  • Preguntar por la canción siendo reproducida con toda su información
  • Mostrar la info relevante en pantalla
  • Repetir cada N segundos para mantener la aplicación autorizada
  • Volver a la autenticación cada vez que mi token de identificación expire

Las cosas salieron más o menos como se esperaba, me tomó mucho tiempo aprender a utilizar bien LVGL, no sabía cómo mostrar imágenes en pantalla, era importante si las imágenes eran PNG o JPEG (Spotify las devuelve en formato JPEG), LVGL parece sólo funcionar con imágenes en formato binario y algunos detalles más. Pero tuve más problemas con dos aspectos importantes de la aplicación: las imágenes y las constantes solicitudes a los servidores de Spotify, así como el tamaño de su respuesta.

Las imágenes

Primera versión con la carátula recortada
Primera versión con la carátula recortada

Como se ve más arriba, la primera versión (y lo más complicado) fue mostrar las imágenes en pantalla. Cuando, después de un buen rato, lo logré (había que especificar el peso de la imagen al momento de crear el objeto de LGVL que se encagaría del resto) me di cuenta de que las imágenes no cabían del todo bien en la pantalla. Además, aún faltaba agregar el texto y todo eso.
Resulta que en LGVL, sobretodo cuando se trata de microcontroladores como este ESP32, llevar a cabo el redimensionado de una imagen es un proceso costoso en términos de cómputo y no quería darle demasiado trabajo al pobre.

¿quizás si le pido a Spotify una imagen más pequeña? Bueno, Spotify mantiene 3 tamaños de imagen para las carátulas de los álbumes, pero ninguna de unos 150x150, que era lo que necesitaba. Las hay de 64x64, 300x300 y 640x640.

Las solicitudes

Cada cierto tiempo, digamos 3 segundos, tenía que hacer una solicitud para mantener el reloj relativamente sincronizado con el backend de Spotify, el problema es que cada una de las solicitudes que hacía demoraba unos milisegundos más de lo que me hubiera gustado y el tamaño de las respuestas era un poco atroz, estaban en el orden de decenas (o hasta centenares) de kilobytes. No pintaba bien para el pequeño ESP32.

Aparte de esto, se me ocurrió que quedaría bien pintar el fondo del color predominante tal cual como lo hace Spotify en sus aplicaciones. Siempre me gustó cómo se veía y también me causaba intriga cómo escogían el color.
Pintar la pantalla entera también tiene un costo no menor.

Con todo esto, resultaba medianamente evidente que seguir poniendo toda la lógica en el dispositivo iba a dejarme con una experiencia de uso mediocre, la lentitud se notaba, la escasa memoria se llenaba rápido y los 3 segundos de retraso que debían existir como máximo se convertían en 5 o 10 debido a todo lo que tenía que hacer el reloj antes de decirme qué era lo nuevo que se estaba escuchando. Sumado a la pobre optimización de mi código, por supuesto.

Cliente y servidor

No esperé a que fuera demasiado evidente y me puse a resolver los problemas mencionados en el Python de toda la vida en una máquina virtual en un servidor x86. En ese entorno la manipulación de imágenes y las solicitudes constantes no representarían ningún tipo de problema, aparte de que trabajar en Python es más fácil debido a la falta de limitaciones y que no todo el código tiene que ser un poquito especial o asíncrono.

Las ventajas eran evidentes, le entregaría al reloj una imagen exactamente del tamaño que necesita y con calidad rebajada para reducir el tamaño; además, al controlar yo la información que llegaba a él, podía quitar de las respuestas de Spotify todo lo que no fuera vital para el funcionamiento de la aplicación y así reducir también el tamaño del JSON que se transmitía, aparte de responder considerablemente más rápido por tratarse de un servidor “local”.

En persona los números no titilan

Finalmente pude terminar el proyecto. El ícono de estado de reproducción indica si se está reproduciendo o no algo (indica estado porque no es un botón, aunque estoy pensando en cambiar eso, así que pasaría a indicar acción), la barra de progreso se mueve con el tiempo, las etiquetas del nombre del artista y canción se mueven con efecto de marquesina si el texto es demasiado largo para el ancho de la pantalla y, lo más importante, logré pintar el fondo de la pantalla del color dominante o resaltante de la imagen.

¿cómo logré esto último? Bueno, ya escribí al respecto en otro post.

El código fuente tanto de la aplicación en el reloj como del servidor intermediario entre Spotify y el Mini Dock se encuentran en este repositorio en Github.