Elegí implementar una arquitectura productor-consumidor con colas de mensajes en memoria (queue.Queue) en lugar de usar un patrón basado en eventos o un bus de mensajes externo como Redis. Esto me permitió mantener el sistema liviano y sin dependencias adicionales para un proyecto de tesis donde la simplicidad de despliegue era prioritaria. La alternativa de Redis habría sido más escalable para múltiples instancias, pero para un solo nodo con ESP32 local, las colas en memoria ofrecen menor latencia y cero configuración de infraestructura.
Opté por MQTT como protocolo de comunicación entre el ESP32 y el servidor Python en vez de HTTP REST o WebSockets. MQTT es ideal para dispositivos IoT con recursos limitados porque tiene overhead mínimo, soporta calidad de servicio (QoS) y permite publicación-suscripción asíncrona. HTTP habría requerido polling constante desde el servidor o endpoints expuestos, lo cual es ineficiente para lecturas periódicas de sensores. Además, MQTT maneja naturalmente la desconexión del ESP32 con mensajes Last Will.
Decidí integrar OpenAI y Elevenlabs para generar recomendaciones de salud y síntesis de voz en tiempo real, en lugar de usar reglas predefinidas o un motor TTS offline. La generación de recomendaciones con IA permite adaptar el mensaje al contexto específico del usuario (nivel UV, tiempo de exposición), algo que reglas estáticas no logran con la misma riqueza. Para la voz, evalué pyttsx3, pero su calidad era inferior y no soportaba voces naturales; Elevenlabs ofrece voces más realistas que mejoran la experiencia del usuario final.
Implementé el manejo de errores con un contador de fallos consecutivos y un timeout en la cola de datos, en vez de reintentos infinitos o excepciones silenciosas. Esto evita que el sistema se quede colgado si el ESP32 deja de enviar datos o si la red falla. La alternativa de reintentar indefinidamente habría ocultado problemas operativos, mientras que lanzar excepciones sin control habría detenido todo el sistema. Con un límite de 3 errores consecutivos y un timeout de 30 segundos, el sistema se detiene de forma controlada y registra la falla para diagnóstico.