Full text
Equation Chapter 1 Section 1 Trabajo Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Autor: Sergio García López Tutora: María Teresa Ariza Gómez Dpto. Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024
iii Trabajo Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Autor: Sergio García López Tutora: María Teresa Ariza Gómez Departamento de Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2024
v Trabajo Fin de Grado: Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Autor: Sergio García López Tutora: María Teresa Ariza Gómez El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros: Presidente: Vocales: Secretario: Acuerdan otorgarle la calificación de: Sevilla, 2024 El Secretario del Tribunal
vii A mi familia y amigos
ix Agradecimientos En primer lugar, quiero expresar mi profundo agradecimiento por el apoyo incondicional de mi familia durante todos estos años de carrera, y por darme consejos para seguir adelante a pesar de las dificultades. A mi madre, por su profundo amor, y por apoyarme y animarme durante este curso tan duro. A mi padre, también por su afecto y apoyo, y por haberme dado indicaciones y orientación durante el desarrollo del proyecto. A mi hermano Nacho, cuya curiosidad e interés por mi trabajo ha supuesto una motivación más que me ha permitido llevarlo a cabo. A mis abuelos, tíos y primos, por sus mensajes de apoyo y cariño desde Jaén. Mi familia merece un lugar especial en esta dedicatoria, pues son el pilar fundamental de mi vida. Gracias a mis amigos de toda la vida: Carmen, Marina, Inés, Irene y Alejandro. A pesar de los distintos caminos que hemos tomado, quiero agradecer que sigamos manteniendo nuestra profunda amistad. Quiero agradecer los años que hemos pasado juntos y los que están por venir, pues junto a mi familia, sois quienes habéis definido mi persona y mi ser. También quiero hacer una mención especial a mi amigo Álvaro, quien pronto será ingeniero al igual que yo, pero en su caso, ingeniero aeroespacial. Nuestro paso por la ETSI ha sido prácticamente paralelo, y al final, él ha sido uno de los pocos que ha llegado hasta aquí junto a mí, desde que entramos en la escuela allá por el 2019. Quiero agradecer su amistad, y especialmente los buenos momentos que hemos pasado hablando sobre la carrera, tecnología e incluso filosofía. De la carrera no solo salgo con conocimientos y experiencias, también con buenos amigos. Quiero agradecer a Chema, Kiko, Pedro y Felipe por haberme acompañado durante este camino. También a quién ya era mi amigo del instituto, Sergio Montañés, a quién le deseo lo mejor en sus últimos años de carrera. Además, quiero hacer una mención especial a mis compañeros del Máster en Ingeniería de Telecomunicación, en especial a Juan Luis, Juanjo y Aitor, por los buenos momentos pasados en clase. Por último, quiero mostrar mi sincero agradecimiento a mi tutora, María Teresa Ariza Gómez. Le estoy profundamente agradecido por haber aceptado mi idea inicial, por sus conocimientos, consejos y orientaciones, y por haberme ayudado a encaminar el proyecto. Sergio García López Sevilla, 2024
Anexo B: Fichero docker-compose.yaml 123
xvii ÍNDICE DE TABLAS Tabla 3-1. Tópicos MQTT del Shelly Plug S 28 Tabla 3-2. Rutas para consultar el consumo por tramos horarios 45 Tabla 3-3. Parámetros para la consulta de precios PVPC en REData API 50 Tabla 4-1. Rutas del servicio REST de consumo y costes 77
xix ÍNDICE DE FIGURAS Figura 1-1. Previsiones en el número de dispositivos inteligentes en hogares para el año 2026 2 Figura 1-2. Número de dispositivos IoT en el mundo 2 Figura 1-3. Arquitectura del sistema domótico 5 Figura 2-1. Enchufe Shelly Plug S 9 Figura 2-2. Portátil OMEN 16 10 Figura 2-3. MQTT 11 Figura 2-4. Eclipse Mosquitto 11 Figura 2-5. NodeRED 11 Figura 2-6. Flask 12 Figura 2-7. Flassger 12 Figura 2-8. SQLAlchemy 12 Figura 2-9. Pytest 13 Figura 2-10. PostgreSQL 13 Figura 2-11. Docker 14 Figura 2-12. Docker-Compose 14 Figura 2-13. Ubuntu 14 Figura 2-14. Virtualbox 15 Figura 2-15. Microsoft Azure 15 Figura 2-16. Wireshark 16 Figura 2-17. Sublime Text 16 Figura 3-1. Página de la imagen oficial de Eclipse Mosquitto 18 Figura 3-2. Definición del contenedor Mosquitto en Docker-Compose 18 Figura 3-3. Contenido del fichero mosquitto.conf 19 Figura 3-4. Interfaz web de configuración del Shelly Plug S 20 Figura 3-5. Opciones avanzadas de desarrollador del Shelly Plug S 21 Figura 3-6. Activación del uso de MQTT en el Shelly Plug S 21 Figura 3-7. Configuración de la dirección del broker MQTT en el Shelly Plug S 22 Figura 3-8. Guía para ejecutar NodeRED como contenedor Docker 23 Figura 3-9. Definición del contenedor NodeRED en Docker-Compose 24 Figura 3-10. Modificaciones del fichero settings.js 25 Figura 3-11. Ejemplo de uso de la herramienta de hashing Bcrypt de NodeRED 25 Figura 3-12. Login mediante usuario y contraseña para acceder al editor de flujos de NodeRED 26
Figura 3-13. Aviso de certificado no válido al acceder a NodeRED 26 Figura 3-14. Ejemplo de uso de mosquitto_sub para recibir los mensajes del Shelly Plug S 27 Figura 3-15. Interfaz web del editor de NodeRED 28 Figura 3-16. Nodo de conexión a un broker MQTT y suscripción a tópicos 29 Figura 3-17. Configuración del nodo MQTT de suscripción 29 Figura 3-18. Configuración del broker MQTT en NodeRED 30 Figura 3-19. Medidas de potencia visualizadas mediante la herramienta de depuración de NodeRED 31 Figura 3-20. Flujo NodeRED para la recolección y almacenamiento de medidas de potencia 31 Figura 3-21. Código de la función obtenerPotencia 32 Figura 3-22. Medidas de potencia con fecha de medición en NodeRED 32 Figura 3-23. Configuración de un nodo HTTP POST para publicar medidas de potencia 33 Figura 3-24. Respuesta satisfactoria tras almacenar una medida de potencia 34 Figura 3-25. Diagrama de paso de mensajes para la recolección de medidas de potencia 34 Figura 3-26. Flujo NodeRED para el borrado de medidas de potencia 34 Figura 3-27. Programación de un evento de borrado de medidas periódico 35 Figura 3-28. Configuración de un nodo HTTP DELETE para el borrado de medidas de potencia 35 Figura 3-29. Respuesta satisfactoria tras borrar las medidas de potencia 36 Figura 3-30. Flujo NodeRED para el control del enchufe inteligente 36 Figura 3-31. Configuración del nodo de control de apagado y encendido 37 Figura 3-32. Botón para el control de apagado y encendido del enchufe en la interfaz de usuario 37 Figura 3-33. Diagrama de paso de mensajes para el control del Shelly Plug S 38 Figura 3-34. Configuración del nodo contador de potencia 39 Figura 3-35. Contador de potencia en la interfaz de usuario 40 Figura 3-36. Flujo NodeRED para visualizar la potencia consumida a lo largo del tiempo 40 Figura 3-37. Código de la función prepararMedidasPotencia 41 Figura 3-38. Configuración del nodo de gráfica para representar la potencia a lo largo del tiempo 42 Figura 3-39. Representación gráfica de la potencia consumida en el enchufe a lo largo del tiempo 43 Figura 3-40. Diagrama de paso de mensajes para la visualización de la potencia consumida 43 Figura 3-41. Flujo NodeRED para la visualización del consumo en la última hora 44 Figura 3-42. Contador de consumo en la interfaz de usuario 44 Figura 3-43. Flujo NodeRED para la visualización del consumo por tramos horarios 44 Figura 3-44. Código de la función consumoMadrugada 45 Figura 3-45. Representación gráfica del consumo energético por tramos horarios 46 Figura 3-46. Flujo NodeRED para la visualización del consumo en cada hora del día 46 Figura 3-47. Representación gráfica del consumo en cada hora del día 47 Figura 3-48. Consulta de precios de la tarifa PVPC en la página web de Red Eléctrica 48 Figura 3-49. Consulta de precios de la tarifa PVPC en REData API 49 Figura 3-50. Flujo NodeRED encargado de la consulta de precios PVPC en REData API. Parte 1 50 Figura 3-51. Flujo NodeRED encargado de la consulta de precios PVPC en REData API. Parte 2 50
xxi Figura 3-52. Código de la función prepararURL 51 Figura 3-53. Código de la función prepararPrecios 52 Figura 3-54. Representación gráfica de los precios de la tarifa PVPC para cada hora del día 53 Figura 3-55. Diagrama de paso de mensajes para la consulta de precios de la tarifa PVPC 53 Figura 3-56. Flujo NodeRED encargado del cálculo de costes del consumo. Parte 1 54 Figura 3-57. Flujo NodeRED encargado del cálculo de costes del consumo. Parte 2 54 Figura 3-58. Código de la función calcularCoste 55 Figura 3-59. Representación gráfica del coste por hora y del coste total del día 56 Figura 3-60. Flujo NodeRED encargado de almacenar los datos de coste diario 57 Figura 3-61. Flujo NodeRED encargado de obtener el histórico de consumo 57 Figura 3-62. Representación gráfica del histórico de consumo 58 Figura 3-63. Flujo NodeRED encargado de obtener el histórico de costes 58 Figura 3-64. Representación gráfica del histórico de costes 59 Figura 3-65. Diagrama de paso de mensajes para la consulta de históricos 60 Figura 3-66. Flujos NodeRED para la gestión de datos del sistema domótico 61 Figura 3-67. Botones para el borrado de datos de la base de datos 61 Figura 3-68. Notificación de confirmación de borrado de datos 62 Figura 3-69. Notificación para informar de que los datos han sido borrados con éxito 62 Figura 3-70. Opción Manage Palette de NodeRED 63 Figura 3-71. Nodos del módulo node-red-dashboard 63 Figura 3-72. Herramienta para la disposición de elementos en la interfaz de usuario 64 Figura 3-73. Página principal de la interfaz de usuario 65 Figura 3-74. Navegación por la interfaz de usuario 65 Figura 3-75. Monitorización de consumo 66 Figura 3-76. Consumo diario 67 Figura 3-77. Histórico de consumo 68 Figura 3-78. Precios Red Eléctrica (PVPC) 69 Figura 3-79. Coste por hora 70 Figura 3-80. Histórico de costes 71 Figura 3-81. Gestión de datos 71 Figura 4-1. Definición del contenedor PostgreSQL en Docker-Compose 74 Figura 4-2. Contenido del fichero base_datos.sh 75 Figura 4-3. Contenido del fichero crear_tablas.sql 75 Figura 4-4. Especificación OpenAPI del servicio REST de consumo y costes 76 Figura 4-5. Petición GET a /ping 78 Figura 4-6. Código de la función ping en rutas.py 78 Figura 4-7. Petición GET a /shelly-plug/potencia/medidas (sin parámetros) 79 Figura 4-8. Petición GET a /shelly-plug/potencia/medidas (con parámetros) 80 Figura 4-9. Cuerpo de la petición POST a /shelly-plug/potencia/medidas 81
Figura 4-10. Petición POST a /shelly-plug/potencia/medidas 81 Figura 4-11. Petición DELETE a /shelly-plug/potencia/medidas con identificador 82 Figura 4-12. Petición DELETE a /shelly-plug/potencia/medidas sin identificador 83 Figura 4-13. Petición GET a /shelly-plug/consumo (sin parámetros) 83 Figura 4-14: Petición GET a /shelly-plug/consumo (con parámetros) 84 Figura 4-15. Petición GET a /shelly-plug/consumo/consumo-por-hora 85 Figura 4-16. Petición GET a /shelly-plug/consumo/medidas 86 Figura 4-17. Petición DELETE a /shelly-plug/consumo/medidas 87 Figura 4-18. Petición GET a /shelly-plug/costes 87 Figura 4-19. Cuerpo de la petición POST a /shelly-plug/costes 88 Figura 4-20. Petición POST a /shelly-plug/costes 88 Figura 4-21. Petición DELETE a /shelly-plug/costes 89 Figura 4-22. Código de la función calcula_consumo en utilidades.py 89 Figura 4-23. Fórmula para la estimación del consumo eléctrico 90 Figura 4-24. Extracto de la función obtener_consumo en rutas.py 91 Figura 4-25. Extracto de la función nueva_medida_potencia en rutas.py. Parte 1 92 Figura 4-26. Extracto de la función nueva_medida_potencia en rutas.py. Parte 2 93 Figura 4-27. Contenido del fichero modelos.py 94 Figura 4-28. Contenido del fichero __init__.py 95 Figura 4-29. Ejemplos de comentarios Flassger para documentar las rutas del servicio REST 95 Figura 4-30. Acceso a la interfaz Swagger del servicio REST 96 Figura 4-31. Interacción con las rutas del servicio REST mediante Swagger 96 Figura 4-32. Contenido del fichero pruebas.sh 97 Figura 4-33. Inserción de datos de ejemplo en tablas_tests.sql 97 Figura 4-34. Configuración de la conexión a la base de datos de pruebas en test_rutas.py 98 Figura 4-35. Función de pruebas de la ruta /shelly-plug/potencia/medidas (GET) en test_rutas.py 99 Figura 4-36. Informe con los resultados de las pruebas del servicio REST. Parte 1 100 Figura 4-37. Informe con los resultados de las pruebas del servicio REST. Parte 2 100 Figura 4-38. Dockerfile del servicio REST de consumo y costes 101 Figura 4-39: Contenido del fichero requirements.txt con las dependencias de la aplicación Flask 102 Figura 4-40. Contenido del fichero run.py 102 Figura 4-41. Definición del contenedor con el servicio REST de consumo y costes en Docker-Compose 102 Figura 4-42. Contenido del fichero de configuración config.py 103 Figura 5-1. Panel de control del portal de Azure 106 Figura 5-2. Servicios ofrecidos por Azure 106 Figura 5-3. Opciones de creación de una máquina virtual en Azure 107 Figura 5-4. Detalles de la máquina virtual creada en Azure 108 Figura 5-5. Reglas de entrada del firewall de la máquina virtual 108 Figura 5-6. Ficheros del directorio TFG/docker 109
xxiii Figura 5-7. Arranque del sistema domótico utilizando Docker-Compose 109 Figura 5-8. Acceso a la interfaz de usuario de NodeRED de forma remota 110 Figura 5-9. Consulta de los logs de los contenedores utilizando Docker Compose 110 Figura 5-10. Reinicio y parada del sistema domótico utilizando Docker Compose 110
Glosario TIC Tecnologías de la Información y Comunicación API Application Programming Interface MQTT Message Queuing Telemetry Transport REST Representational State Transfer IoT Internet of Things IP Internet Protocol PVPC Precio Voluntario para el Pequeño Consumidor SQL Structured Query Language JSON JavaScript Object Notation YAML Yet Another Markup Language GNU GNU is Not Unix TCP Transmission Control Protocol IT Information Technology HTTP Hypertext Transfer Protocol HTTPS Hypertext Transfer Protocol Secure URL Uniform Resource Locator ORM Object Relational Mapping CA Certificate Authority TLS Transport Layer Security DNS Domain Name System SSH Secure Shell
1 1 INTRODUCCIÓN 1.1 Motivación En los últimos años, el término “hogar inteligente” ha dejado de ser una proyección de futuro y está empezando a convertirse en una realidad para nuestra sociedad actual. La domótica, o automatización del hogar, ha emergido como una tecnología revolucionaria que transforma la forma en que interactuamos con nuestro entorno doméstico. Desde el encendido automático de las luces, puertas automáticas, neveras inteligentes, cámaras de vigilancia IP e incluso la preparación del café por la mañana. En la figura 1-1 se muestran algunas estimaciones del número de dispositivos domésticos inteligentes en el mundo. En el año 2022, aproximadamente 131 millones de hogares disponían de altavoces inteligentes, siendo los más populares Amazon Echo con Alexa como asistente virtual y Google Home. No obstante, se prevé que para el año 2026 esta cifra aumente hasta los 300 millones de hogares. Además, se espera que en los próximos años aumente la integración de otras clases de dispositivos en los hogares, tales como neveras y lavadoras inteligentes, robots aspiradores, detectores de humo, cámaras de seguridad, etc [1]. Caminante, no hay camino, se hace camino al andar. - Antonio Machado -
9 2 TECNOLOGÍAS UTILIZADAS 2.1 Tecnologías hardware 2.1.1 Enchufe inteligente Shelly Plug S El Shelly Plug S [3] es un enchufe inteligente fabricado por Shelly Group, una empresa especializada en la fabricación de dispositivos domóticos, entre los que destacan enchufes, bombillas, sensores de humedad y temperatura, interruptores, detectores de ventanas y puertas, etc. Este enchufe está diseñado para permitir la conexión y desconexión a la red eléctrica de los dispositivos conectados a él. Se puede configurar y controlar a través de una red Wi-Fi mediante su servidor web local o mediante una aplicación móvil. Puede soportar una potencia máxima de 2500 W. Ofrece integración con servicios cloud como Amazon Alexa o Google Assistant. Además, el Shelly Plug S es compatible con el protocolo MQTT, lo que facilita su integración en sistemas domóticos más complejos. Se trata del elemento fundamental que nos permite hacer el control y monitorización del consumo eléctrico en este sistema. En la figura 2-1 puede verse una imagen del enchufe: Figura 2-1. Enchufe Shelly Plug S Vivimos en una sociedad extremadamente dependiente de la ciencia y la tecnología, en la que casi nadie tiene un mínimo conocimiento en ciencia y tecnología. - Carl Sagan -
Tecnologías utilizadas 10 2.1.2 Portátil OMEN 16 El equipo de trabajo empleado durante el desarrollo del proyecto, incluyendo la implementación y configuración de los componentes software del sistema, ha sido un portátil OMEN 16 [11] de la marca HP, mostrado en la figura 2-2: Figura 2-2. Portátil OMEN 16 Entre sus especificaciones técnicas podemos destacar: • Procesador Intel Core i7-13700HX • Tarjeta gráfica NVIDIA GeForce RTX 4080 (GDDR6 de 12 GB dedicada) • Memoria RAM DDR5-5600 MHz 32 GB (2 x 16 GB) • Almacenamiento SSD 2 TB PCIe Gen4 NVMe TLC M.2 • Sistema operativo Windows 11 Home • Pantalla QHD de 16 pulgadas (hasta 2560 x 1440 píxeles), 240 Hz de frecuencia de refresco. 2.2 Tecnologías software 2.2.1 MQTT MQTT [12] es un protocolo de intercambio de mensajes diseñado específicamente para dispositivos IoT. Se trata de un protocolo ligero que sigue el modelo de comunicación publicador-suscriptor, lo cual permite la publicación y suscripción a tópicos específicos, creando para ello colas de mensajes. Está diseñado para dispositivos con bajos recursos y ancho de banda limitado, lo cual lo hace ideal para dispositivos IoT. Como protocolo de transporte utiliza TCP y ofrece varios niveles de calidad de servicio. En este proyecto, es el protocolo de comunicaciones que nos permite interactuar con el enchufe inteligente.
11 11 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 2-3. MQTT 2.2.2 Eclipse Mosquitto Eclipse Mosquitto [13] es un broker MQTT de código abierto que implementa las versiones 5.0, 3.1.1 y 3.1 del protocolo. Se trata de un broker ligero y adecuado para cualquier tipo de dispositivo, desde sistemas embebidos de baja potencia hasta servidores de alta capacidad. Este proyecto forma parte del Eclipse IoT Working Group y está gestionado por la Fundación Eclipse. Es el broker MQTT que se ha elegido para poder enviar comandos de encendido y apagado al enchufe, así como para obtener los datos de potencia instantánea medidos por este. Figura 2-4. Eclipse Mosquitto 2.2.3 NodeRED Node-RED [4] es una herramienta de programación basada en flujos para aplicaciones orientadas a eventos. Permite interconectar dispositivos hardware, APIs y servicios web, entre otros. Ofrece un editor gráfico accesible desde el navegador que facilita la creación de flujos mediante una amplia gama de nodos y una programación sencilla. Está basado en Node.js y puede ejecutarse en multitud de plataformas, tanto en hardware de bajo coste como en la nube. Además, tiene una biblioteca integrada que permite guardar componentes para su reutilización, así como compartir flujos fácilmente en formato JSON e instalar módulos creados por la comunidad de Node-RED. Se ha utilizado en este proyecto para implementar los aspectos de control y monitorización del sistema, la comunicación con el enchufe inteligente a través del broker MQTT, la interacción con los servicios REST del sistema, y la implementación de la interfaz de usuario. Figura 2-5. NodeRED
Tecnologías utilizadas 12 2.2.4 Flask Flask [14] es un framework ligero de Python usado para crear aplicaciones web de forma rápida y sencilla. Se trata de un framework minimalista y flexible que permite desarrollar desde APIs REST sencillas hasta complejos sistemas web. Además, ofrece una amplia gama de extensiones para agregar funcionalidades según las necesidades de la aplicación. Se ha empleado para desarrollar el servicio REST de consumo y costes del sistema domótico. Figura 2-6. Flask 2.2.5 Flassger Flassger [15] es una extensión de Flask que permite generar una documentación interactiva siguiendo las especificaciones OpenAPI [16]. Facilita la documentación automática de una API REST a partir de comentarios YAML en el código de la aplicación Flask. Además, tiene integrada una interfaz Swagger que permite la interacción y validación de las rutas del servicio REST. Ha sido de utilidad para generar de forma automática la documentación de la API del servicio REST de consumo y costes. Figura 2-7. Flassger 2.2.6 SQLAlchemy SQLAlchemy [17] es una librería de Python que proporciona una forma flexible de interactuar con bases de datos relacionales. Permite a los desarrolladores trabajar con bases de datos SQL mediante programación orientada a objetos, lo cual facilita la creación, manipulación y consulta de datos sin tener que escribir directamente sentencias SQL. En este proyecto se ha empleado para simplificar la interacción con la base de datos desde el servicio REST de consumo y costes, al basarse en un enfoque ORM. Figura 2-8. SQLAlchemy
13 13 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico 2.2.7 Pytest Pytest [18] es un framework de pruebas que permite el desarrollo y ejecución de pruebas unitarias, de integración y funcionales para aplicaciones desarrolladas en Python. Ofrece una sintaxis simple y sencilla para escribir pruebas, una amplia gama de asserts y la generación de informes detallados sobre los resultados de las pruebas. En este proyecto se ha elegido este framework para realizar las pruebas de las rutas expuestas por el servicio REST de consumo y costes. Figura 2-9. Pytest 2.2.8 PostgreSQL PostgreSQL [19] es un sistema de gestión de bases de datos relacionales de código abierto conocido por su fiabilidad, robustez y rendimiento. Debido a estas características, es ampliamente usado en aplicaciones web, empresariales y científicas. Se ha usado para almacenar los datos de potencia generados por el enchufe, los datos de consumo y los de costes. Figura 2-10. PostgreSQL 2.2.9 Docker Docker [7] es un software de código abierto utilizado para desplegar aplicaciones en contenedores mediante tecnologías de virtualización del kernel de Linux, tales como los cgroups y namespaces. Permite encapsular aplicaciones y sus dependencias en un entorno aislado, lo que garantiza la portabilidad de la aplicación y la consistencia del entorno de ejecución, independientemente de la infraestructura que haya por debajo. Se ha utilizado un contenedor Docker para cada uno de los servicios que componen el sistema, facilitando así su gestión y portabilidad.
Tecnologías utilizadas 14 Figura 2-11. Docker 2.2.10 Docker-Compose Docker-Compose [8] es una herramienta usada para definir y ejecutar aplicaciones multi-contenedor en Docker. Facilita la configuración y gestión de servicios, redes y volúmenes a partir de un fichero de configuración YAML. Además, proporciona comandos para crear, iniciar, detener y administrar contenedores de manera conjunta, simplificando así el proceso de desarrollo y despliegue de sistemas basados en múltiples servicios. Docker-Compose ha sido de gran utilidad para gestionar de forma sencilla la definición, configuración y operación de los contenedores del sistema domótico, sin tener que recurrir directamente a comandos Docker. Figura 2-12. Docker-Compose 2.2.11 Ubuntu Ubuntu [20] es una distribución GNU/Linux basada en Debian. Es ampliamente conocido por su facilidad de uso, estabilidad y seguridad, ofreciendo una amplia gama de software gratuito y de código abierto. Es el sistema operativo que se ha usado tanto para la implementación del sistema domótico como para su despliegue en una máquina virtual en la nube de Azure. Figura 2-13. Ubuntu
15 15 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico 2.2.12 Virtualbox Virtualbox [21] es un software de virtualización de código abierto que permite ejecutar y crear máquinas virtuales. Permite tener sistemas operativos invitados (guests) dentro de un sistema operativo anfitrión (host). Es el hipervisor que se ha elegido para crear y ejecutar una máquina virtual Ubuntu en un sistema operativo anfitrión Windows 11, la cual se ha usado para implementar el sistema domótico. Figura 2-14. Virtualbox 2.2.13 Microsoft Azure Microsoft Azure [9] es una plataforma cloud que ofrece servicios de tipo “infraestructura como servicio” y “plataforma como servicio”. Entre estos destacan servicios de almacenamiento, redes, creación de máquinas virtuales, bases de datos o backend para aplicaciones móviles. Es la plataforma que se ha elegido para crear una máquina virtual en la nube en la que se ha desplegado el sistema domótico. Figura 2-15. Microsoft Azure 2.2.14 Wireshark Wireshark [22] es una herramienta open source que permite capturar y analizar tráfico de red en tiempo real. Es utilizado por ingenieros de redes, analistas de ciberseguridad y desarrolladores de aplicaciones para diagnosticar problemas de red, realizar pruebas de seguridad, depurar aplicaciones, y analizar y probar protocolos en una red. Se ha utilizado para solucionar los problemas de comunicación con el enchufe inteligente y depurar el servicio REST de consumo y costes.
Tecnologías utilizadas 16 Figura 2-16. Wireshark 2.2.15 Sublime Text Sublime Text [23] un editor de código caracterizado por su interfaz de usuario limpia y minimalista. Es compatible con múltiples lenguajes de programación y ofrece características avanzadas como resaltado de sintaxis, autocompletado inteligente, búsqueda y reemplazo avanzados, y una gran cantidad de extensiones para ampliar su funcionalidad. Es el editor que se ha elegido para trabajar en la implementación del sistema domótico. Figura 2-17. Sublime Text
17 3 CONTROL Y MONITORIZACIÓN MEDIANTE NODE-RED En este capítulo se detalla la implementación del sistema de control y monitorización del consumo eléctrico mediante Node-RED, incluyendo los mecanismos de comunicación con el enchufe inteligente utilizando el protocolo MQTT. También se abordan las interacciones con el servicio REST de consumo y costes, y con el servicio REST de Red Eléctrica, así como la creación de la interfaz de usuario. 3.1 Despliegue y configuración del broker MQTT Uno de los aspectos fundamentales del sistema es la comunicación con el enchufe inteligente a través del protocolo MQTT. Para ello, es necesario disponer de un broker MQTT, que puede ser uno público, como es el caso del broker de HiveMQ [24], o uno privado. Para este proyecto se ha elegido esta última opción, utilizar un broker MQTT propio usando un contenedor de Eclipse Mosquitto. 3.1.1 Despliegue del contenedor Mosquitto Para cada uno de los contenedores del sistema, se hará uso de imágenes Docker que pueden ser obtenidas desde Docker Hub [25], el repositorio público de imágenes Docker más conocido y utilizado en la industria IT. Para desplegar un contenedor Mosquitto, podemos seguir los pasos indicados en la página de la imagen oficial de Eclipse Mosquitto [26] , mostrada en la figura 3-1: Si no puedes medirlo no puedes mejorarlo. - Peter Drucker -
Control y monitorización mediante Node-RED 24 Figura 3-9. Definición del contenedor NodeRED en Docker-Compose La definición de dicho contenedor consiste en: • Crear un servicio en Docker-Compose llamado nodered. • Crear un contenedor llamado nodered, asociado al servicio nodered. • Crear dicho contenedor a partir de una versión concreta de la imagen de NodeRED. A diferencia del caso del contenedor Mosquitto, no utilizaremos la etiqueta latest para evitar posibles incompatibilidades con versiones futuras de NodeRED que impidan utilizan los flujos que se han programado. Para este proyecto se está utilizando la etiqueta 3.1-debian. • Abrir el puerto 443 de la máquina anfitriona y redirigirlo al puerto 1880 del contenedor. Por defecto, el puerto estándar de NodeRED es el 1880. Sin embargo, para simplificar el acceso mediante navegador al editor de flujos y a la interfaz de usuario, se hará uso de un puerto estándar web, que en el caso de HTTPS es el 443. • Reiniciar automáticamente el contenedor en caso de que se detenga, garantizando que el servicio se esté ejecutando en todo momento. • Compartir el directorio ./nodered/data del host (partiendo del directorio de trabajo donde está el fichero docker-compose.yaml) con el directorio /data del contenedor. De esta forma, podremos acceder de forma sencilla a los ficheros de configuración de NodeRED, a los ficheros de flujos y almacenar certificados digitales desde la propia máquina anfitriona. • Establecer la variable de entorno TZ (Time Zone) a la zona horaria de Madrid. 3.3.2 Configuración de NodeRED El fichero que nos permite cambiar la configuración de NodeRED es el fichero settings.js, que se encuentra dentro del directorio /data del contenedor. NodeRED proporciona una guía de usuario básica [28] que aborda de forma general lo que se puede configurar en este fichero. No obstante, existen guías más detalladas y especializadas sobre este fichero, como por ejemplo, medidas para securizar NodeRED [29]. En la figura 3-10 se muestra un extracto del fichero settings.js con las modificaciones que se han realizado en este proyecto:
25 25 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-10. Modificaciones del fichero settings.js Como puede verse en la figura 3-10, la configuración de NodeRED se realiza creando y modificando objetos JSON en el fichero settings.js. El primer cambio en la configuración consiste en la creación de un usuario administrador para securizar el acceso a la interfaz web del editor de flujos de NodeRED. Para ello, se establece un nombre de usuario, una contraseña y los permisos del usuario. En NodeRED, a las contraseñas se les debe aplicar un hash para almacenarlas de una forma más segura. Por defecto, NodeRED utiliza el algoritmo Bcrypt [30], y provee una herramienta de línea de comandos llamada “node-red admin hash-pw” para generar el hash de una contraseña en texto claro. En la figura 3-11 se muestra un ejemplo de uso de dicha utilidad de NodeRED, obteniendo el hash Bcrypt de la contraseña “hola123”: Figura 3-11. Ejemplo de uso de la herramienta de hashing Bcrypt de NodeRED Además, a este usuario administrador se le están asignando permisos de lectura y escritura del editor de NodeRED. También cabría la posibilidad de crear un usuario con acceso al editor que solo tuviera permisos de lectura. Como resultado, en el sistema domótico únicamente el usuario administrador tiene acceso al editor de flujos de NodeRED, teniendo que autenticarse con su usuario y contraseña, como puede verse en la figura 3-12:
Control y monitorización mediante Node-RED 26 Figura 3-12. Login mediante usuario y contraseña para acceder al editor de flujos de NodeRED Al estar basado en Node.js, NodeRED funciona como un servicio web. Por lo tanto, para acceder tanto al editor de flujos como a la interfaz de usuario, debemos navegar a las rutas correspondientes. Por defecto, el editor de flujos de NodeRED está expuesto en la ruta raíz (ruta /), mientras que la interfaz de usuario está expuesta en la ruta /ui. Para hacer que el acceso a estos recursos sea más intuitivo, se han modificado sus rutas. Con la configuración mostrada en la figura 3-10, la interfaz de usuario es accesible directamente desde la ruta raíz, mientras que para acceder al editor de flujos debemos navegar a la ruta /editor. El último aspecto de configuración del fichero settings.js mostrado en la figura 3-10 es la configuración del uso de HTTPS en NodeRED, con el objetivo de garantizar la seguridad de la información de los usuarios al utilizar la interfaz del sistema domótico. Para ello, es necesario el uso de certificados digitales x509 [31]. En este proyecto se ha hecho uso de la herramienta OpenSSL [32], que permite crear y firmar certificados digitales desde la línea de comandos. No obstante, este certificado al haber sido autofirmado, no está firmado o reconocido por una CA. Por lo tanto, en la gran mayoría de navegadores se mostrará un aviso crítico de seguridad indicando que el certificado proporcionado por el servidor web no es válido, como puede verse en la figura 3-13. Sin embargo, esto no supone ningún impedimento a la hora de usar el sistema domótico, y simplemente habría que utilizar un certificado reconocido por una CA en un entorno de producción real. Figura 3-13. Aviso de certificado no válido al acceder a NodeRED Como comentábamos, para poder utilizar HTTPS, NodeRED necesita tanto el certificado como la clave privada con la que se firmó el certificado. Para ello, se ha creado un directorio llamado certs dentro de la ruta /data donde se han almacenado estos ficheros generados mediante OpenSSL. Una vez que el contenedor puede acceder a estos ficheros, en la configuración de NodeRED ya podemos indicar cuál es el certificado y la
27 27 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico clave privada que se deben usar. 3.4 Comunicación con el enchufe inteligente mediante MQTT Una vez que se han desplegado los contenedores de Mosquitto y NodeRED, y se le ha configurado un broker MQTT al enchufe inteligente, ya somos capaces de comunicarnos con el enchufe. El primer paso consiste en identificar los tópicos MQTT en los cuales el enchufe está publicando información. Para ello, podemos consultar la documentación del Shelly Plug S en la que se especifican los tópicos usados por el enchufe inteligente [33]. No obstante, para identificar dichos tópicos, también podemos usar una herramienta de línea de comandos proporcionada por Mosquitto llamada “mosquitto_sub” [34]. Esta herramienta nos permite suscribirnos a tópicos MQTT para que el broker nos reenvíe los mensajes que se han publicado en dichos tópicos. En la figura 3-14 se muestra un ejemplo de uso de “mosquitto_sub” realizando una suscripción a los mensajes publicados por el enchufe inteligente. Para ello, podemos suscribirnos al tópico comodín de MQTT, que es el símbolo almohadilla: #, el cual supone suscribirse a los mensajes de cualquier tópico. Figura 3-14. Ejemplo de uso de mosquitto_sub para recibir los mensajes del Shelly Plug S En la documentación del Shelly Plug S [33] se nos explica que todos los tópicos usados por el enchufe empiezan por el prefijo shellies. Para identificar al dispositivo en los mensajes publicados, por defecto se usa el identificador del dispositivo: shellies/<model>-<deviceid>. Sin embargo, en la configuración del enchufe realizada en la Sección 3.2 (Configuración del enchufe inteligente) se puede cambiar ese prefijo por uno personalizado, que en nuestro caso es el prefijo enchufe, por simplicidad. Como resultado, todos los tópicos de los mensajes MQTT del Shelly Plug S empiezan por shellies/enchufe. El enchufe Shelly Plug S publica diversa información en el broker: estado del enchufe, potencia instantánea, energía consumida total, temperatura medida en el enchufe, sobrecalentamiento, etc. En este proyecto se ha hecho uso de los tópicos MQTT mostrados en la tabla 3-1:
Control y monitorización mediante Node-RED 28 Tópico Acción realizada por el Shelly Plug S Descripción shellies/enchufe/relay/0/power Publicación Potencia instantánea consumida en vatios (W) shellies/enchufe/relay/0 Publicación Estado del enchufe. Puede estar encendido (on), apagado (off) o en sobrecorriente (overpower) shellies/enchufe/relay/0/command Suscripción Recepción de comandos de control. Pueden ser encender (on), apagar (off) o conmutar (toggle) Tabla 3-1. Tópicos MQTT del Shelly Plug S Los tópicos mencionados en la tabla 3-1 nos permiten obtener la potencia instantánea en vatios medida por el enchufe, conocer si el enchufe está apagado o encendido, y controlar al enchufe encendiéndolo o apagándolo mediante comandos de control. 3.5 Recolección de las medidas de potencia del enchufe inteligente Como ya se comentó en la Sección 2.2 (Tecnologías software), NodeRED es una herramienta de programación basada en la creación de flujos. Un flujo en NodeRED consiste en una secuencia de nodos conectados entre sí que realizan tareas de procesamiento y que van pasando mensajes al siguiente nodo, creando así un flujo lógico de información. Usualmente, el flujo de información se origina en un evento externo a NodeRED, como podría ser la recepción de un mensaje MQTT, o una petición HTTP. Sin embargo, también es muy común que se originen eventos dentro del propio NodeRED, típicamente mediante el uso de temporizadores. En la figura 3-15 se muestra la interfaz web del editor de NodeRED que nos permite programar este tipo de flujos de forma gráfica: Figura 3-15. Interfaz web del editor de NodeRED
29 29 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Para recibir en NodeRED las medidas de potencia instantánea publicadas en el broker MQTT, debemos utilizar uno de los nodos que nos permite la conexión a un broker y la suscripción a tópicos. Para ello, debemos instanciar este nodo y configurarlo. En la figura 3-16 se muestra dicho nodo y en la figura 3-17 se muestra su configuración: Figura 3-16. Nodo de conexión a un broker MQTT y suscripción a tópicos Figura 3-17. Configuración del nodo MQTT de suscripción Lo más relevante en esta configuración consiste en elegir el broker MQTT, la acción a realizar (que consiste en suscribirse a un único tópico), y escribir el tópico al cual queremos suscribirnos. Como ya se explicó en la Sección 3.4 (Comunicación con el enchufe inteligente mediante MQTT), el tópico en el que el Shelly Plug S publica las medidas de potencia que va tomando es el tópico shellies/enchufe/relay/0/power. En cuanto a qué broker debe usarse, debemos definirlo y configurarlo. En este proyecto lo hemos identificado
Control y monitorización mediante Node-RED 30 como Broker Privado Docker, ya que se trata del broker Mosquitto creado mediante Docker que se explicó en la Sección 3.1 (Despliegue y configuración del broker MQTT). Para ello, indicamos cuál es su dirección IP o su nombre de dominio, y el puerto que debe utilizarse. Gracias a que Docker-Compose incorpora un servidor DNS interno [35], podemos tener conectividad entre contenedores utilizando simplemente el nombre del contenedor correspondiente, en vez de tener que especificar su dirección IP. Por ello, en la configuración del broker MQTT mostrada en la figura 3-18, nos basta con indicar cuál es el nombre del contenedor con el broker MQTT, que es mosquitto: Figura 3-18. Configuración del broker MQTT en NodeRED Una vez realizada esta configuración y mediante el uso de nodos de depuración, ya podemos visualizar desde NodeRED las medidas de potencia proporcionadas por el Shelly Plug S, como puede verse en la figura 3-19:
31 31 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-19. Medidas de potencia visualizadas mediante la herramienta de depuración de NodeRED Tras realizar estos pasos, ya podemos hacer un seguimiento periódico de la potencia que se está consumiendo a través del enchufe. Lo siguiente que debemos hacer es almacenar las medidas de potencia en una base de datos a través del servicio REST de consumo y costes. La implementación y funcionamiento en detalle de dicho servicio REST se explica en el Capítulo 4 (Servicio REST de consumo y costes). Para ello, hacemos uso del flujo NodeRED mostrado en la figura 3-20: Figura 3-20. Flujo NodeRED para la recolección y almacenamiento de medidas de potencia Para empezar, en dicho flujo limitamos la cantidad de mensajes recibidos desde el broker MQTT a un mensaje cada 30 segundos (nodo limit 1 msg/30s), para evitar tener una cantidad de medidas de potencia excesiva en la base de datos. No obstante, hay que recalcar que las medidas de potencia son borradas de la base de datos tras finalizar el día, puesto que dejan de ser de utilidad una vez que se ha calculado el consumo eléctrico y los costes de ese día en concreto. Con este límite, en la base de datos habrá un máximo de 2880 medidas de potencia cada día. El siguiente nodo consiste en una función JavaScript llamada obtenerPotencia, cuyo código se muestra en la figura 3-21:
Control y monitorización mediante Node-RED 32 Figura 3-21. Código de la función obtenerPotencia En dicha función, obtenemos la fecha y hora a la que hemos obtenido la medida de potencia desde el broker MQTT y creamos un objeto JSON compuesto por la fecha de la medida y su valor de potencia. El objeto que típicamente se intercambia entre los nodos de NodeRED es el objeto msg. De forma general, la información del mensaje se almacena en el atributo payload. Por lo tanto, en esta función lo que hacemos es obtener el valor de potencia accediendo al atributo msg.payload y modificamos dicho atributo para que el siguiente nodo del flujo obtenga un objeto JSON con la fecha de la medida y el valor de potencia, como puede verse en la figura 3-22: Figura 3-22. Medidas de potencia con fecha de medición en NodeRED
33 33 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico El último nodo del flujo mostrado en la figura 3-20 consiste en una petición HTTP POST al servicio REST de consumo y costes para almacenar la medida de potencia en la base de datos. La configuración de este nodo se muestra en la figura 3-23: Figura 3-23. Configuración de un nodo HTTP POST para publicar medidas de potencia En esta configuración indicamos que se debe realizar una petición POST a la URL http://python_rest:10000/shelly-plug/potencia/medidas. El nombre de dominio python_rest se corresponde con el nombre del contenedor en el que se está ejecutando el servicio REST de consumo y costes (aceptando peticiones en el puerto 10000). La ruta shelly-plug/potencia/medidas es la ruta del servicio REST que nos permite almacenar las medidas de potencia, como se explicará en el Capítulo 4 (Servicio REST de consumo y costes). Como resultado, una vez que se ha almacenado con éxito una medida de potencia en la base de datos, obtenemos una respuesta satisfactoria desde el servicio REST, como puede verse en la figura 3-24:
Control y monitorización mediante Node-RED 40 Figura 3-35. Contador de potencia en la interfaz de usuario Sin embargo, a partir de las medidas de potencia instantánea almacenadas en la base de datos, podemos hacer un seguimiento de la potencia consumida a lo largo del tiempo. Para ello, en el servicio REST de consumo y costes se han implementado rutas que devuelven esos datos de potencia. Además, haremos uso de nodos de interfaz gráfica que nos permitirán graficar la potencia instantánea medida por el enchufe a lo largo del tiempo. El flujo NodeRED encargado de realizar estas tareas se muestra en la figura 3-36: Figura 3-36. Flujo NodeRED para visualizar la potencia consumida a lo largo del tiempo Cada 30 segundos actualizaremos la gráfica que muestra la potencia instantánea a lo largo del tiempo. Para ello, se hará una petición HTTP GET a la ruta /shelly-plug/potencia/medidas del servicio REST de consumo y costes. Si a esta ruta no se le especifica el rango horario en el que se quieren estas medidas en el query string, se obtendrán las medidas de potencia registradas en la última hora. En el siguiente nodo, utilizamos una función JavaScript llamada prepararMedidasPotencia para preparar los datos de potencia en un formato de serie temporal, como puede verse en la figura 3-37. Este formato es necesario para poder representar de forma gráfica la potencia a lo largo del tiempo.
41 41 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-37. Código de la función prepararMedidasPotencia El último nodo es el que nos permite graficar una serie temporal. La configuración de este nodo se muestra en la figura 3-38. En este caso, como se están obteniendo las medidas de potencia registradas en la última hora, los límites del eje horizontal de la gráfica se establecen desde hace una hora en adelante. Además, el valor del eje horizontal indica el tiempo en horas y minutos, mientras que el valor del eje vertical indica la potencia consumida en vatios. Por último, la estrategia de interpolación elegida es step. Como se están tomando medidas cada 30 segundos, se asume que la potencia consumida no cambiará drásticamente entre varias medidas seguidas, manteniendo un valor constante (lo cual suele ser lo común en la mayoría de los electrodomésticos). Por este motivo, esta estrategia de interpolación es la más acertada para mostrar cómo se está midiendo la potencia en este sistema. Sin embargo, otra opción de interpolación que se podría haber elegido es linear.
Control y monitorización mediante Node-RED 42 Figura 3-38. Configuración del nodo de gráfica para representar la potencia a lo largo del tiempo Gracias a estas configuraciones, en la interfaz de usuario podremos visualizar de forma muy práctica la potencia en vatios consumida en el enchufe a lo largo del tiempo, como puede verse en la figura 3-39:
43 43 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-39. Representación gráfica de la potencia consumida en el enchufe a lo largo del tiempo De forma general, siempre que el usuario visualice datos de potencia, consumos o costes en NodeRED, se realizará un intercambio de mensajes similar al de la figura 3-40. En dicha figura se muestra un diagrama de paso de mensajes para la visualización de la potencia consumida en el enchufe: Figura 3-40. Diagrama de paso de mensajes para la visualización de la potencia consumida 3.8 Monitorización del consumo Uno de los aspectos fundamentales de este proyecto es el seguimiento del consumo eléctrico. Como bien es sabido, el consumo eléctrico no es más que la potencia eléctrica que se ha consumido durante un periodo de tiempo. El servicio REST de consumo y costes explicado en el Capítulo 4 (Servicio REST de consumo y costes) proporciona una serie de rutas que realizan el cálculo del consumo a partir de las medidas de potencia que se han almacenado en la base de datos. Por lo tanto, podremos visualizar de forma relativamente sencilla el consumo energético en NodeRED mediante consultas a las rutas del servicio REST, delegando las tareas de cálculo a dicho servicio.
Control y monitorización mediante Node-RED 44 3.8.1 Consumo en la última hora Para la consulta del consumo energético que ha habido durante la última hora, se ha implementado un flujo en NodeRED que de forma periódica realiza una petición HTTP GET a la ruta /shelly-plug/consumo del servicio REST de consumo y costes. Esta ruta permite obtener el consumo energético en vatios-hora calculado desde una hora inicio a una hora fin si ambas son proporcionadas en el query string de la petición HTTP. Si no se proporciona ningún parámetro, dicha ruta devuelve el consumo calculado en la última hora. Posteriormente, se utiliza una función JavaScript llamada prepararConsumo que simplemente obtiene el valor de consumo de la respuesta proporcionada por el servicio REST de tal forma que pueda ser representado en un nodo de tipo contador. La estructura de dicho flujo se muestra en la figura 3-41: Figura 3-41. Flujo NodeRED para la visualización del consumo en la última hora De forma similar al contador que permite visualizar la potencia medida por el enchufe, en la figura 3-42 se muestra un contador que permite ver el consumo en vatios-hora que se ha producido en la última hora: Figura 3-42. Contador de consumo en la interfaz de usuario 3.8.2 Consumo por tramos horarios El flujo NodeRED mostrado en la figura 3-43 permite consultar de forma periódica el consumo que se ha producido en el día desglosado en cuatro tramos horarios: madrugada, mañana, tarde y noche. Como se comentó previamente, si en la petición GET a la ruta /shelly-plug/consumo proporcionamos parámetros de hora de inicio y fin, obtendremos el consumo que se ha producido en ese intervalo de tiempo. Figura 3-43. Flujo NodeRED para la visualización del consumo por tramos horarios
45 45 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico En este flujo se realizan cuatro peticiones HTTP GET a las rutas mostradas en la tabla 3-2 para obtener el consumo del tramo correspondiente: Tramo Horas Ruta Madrugada 00:00-05:59 /shelly-plug/consumo?hora_inicio=00:00&hora_fin=05:59 Mañana 06:00-11:59 /shelly-plug/consumo?hora_inicio=06:00&hora_fin=11:59 Tarde 12:00-18:59 /shelly-plug/consumo?hora_inicio=12:00&hora_fin=18:59 Noche 19:00-23:59 /shelly-plug/consumo?hora_inicio=19:00&hora_fin=23:59 Tabla 3-2. Rutas para consultar el consumo por tramos horarios Posteriormente, se utiliza una función JavaScript en cada caso para crear un objeto JSON que contiene el tramo horario y el valor de consumo de ese tramo. En la figura 3-43 se muestra el código JavaScript para el caso del consumo en la madrugada: Figura 3-44. Código de la función consumoMadrugada Para facilitar el manejo de los cuatro datos de consumo, en la figura 3-43 se puede ver que se hace uso de un nodo join 4 para juntar los mensajes de los cuatro nodos anteriores en una lista. Gracias a esto, en la función prepararTramos podemos manipular estos datos de consumo para que puedan ser representados en una gráfica de barras. Para ello, se hace uso de un nodo de tipo gráfica similar al que se utilizó para representar la potencia a lo largo del tiempo, con la diferencia de que ahora se ha configurado para que se represente como gráfica de barras. Como resultado, en la interfaz de usuario podemos ver el consumo que se ha producido en el día en cuatro tramos horarios, como puede verse en la figura 3-45:
Control y monitorización mediante Node-RED 46 Figura 3-45. Representación gráfica del consumo energético por tramos horarios 3.8.3 Consumo en cada hora del día De forma similar, podemos obtener el consumo desglosado en cada una de las 24 horas del día. Sin embargo, para simplificar la programación en NodeRED, se ha creado una ruta en el servicio REST de consumo y costes llamada /shelly-plug/consumo/consumo-por-hora. Cuando se hace una petición GET, esta ruta devuelve una lista con 24 valores de consumo para cada una de las horas del día, empezando desde las 00:00-00:59 hasta las 23:00-23:59. De esta forma, podemos consultar el consumo para cada hora del día de una forma mucho más eficiente, en vez de tener que realizar 24 peticiones GET a la ruta /shelly-plug/consumo. El flujo NodeRED que realiza esta consulta y muestra los resultados en una gráfica de barras se puede ver en la figura 3-46: Figura 3-46. Flujo NodeRED para la visualización del consumo en cada hora del día En este caso, el código JavaScript se ha separado en dos funciones distintas: prepararConsumoHoras y prepararGraficaConsumos. Esto se debe a que los datos de consumo por horas serán necesarios para hacer el cálculo de los costes de esos consumos. Sin embargo, para poder representar estos datos en una gráfica de barras primero hay que pasarlos a un formato distinto, lo cual justifica la separación del código en dos funciones que tienen salidas distintas. En la figura 3-47 se muestra la gráfica de barras (en este caso, horizontal) con los consumos producidos en cada hora del día:
47 47 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-47. Representación gráfica del consumo en cada hora del día 3.9 Consulta de precios de la electricidad Para hacer una estimación de los costes del consumo eléctrico, debemos conocer cuáles son los precios de la electricidad. Si bien el precio depende de la tarifa que el usuario tenga contratado con la empresa que le suministra electricidad, podemos tener como referencia la tarifa PVPC [6]. De forma general, se suelen contratar tarifas denominadas de mercado libre. Este tipo de tarifas dependen de la empresa comercializadora que las ofrezca, y pueden tener un precio fijo o variable según el horario, posibilidad de tener el suministro de electricidad y de gas con la misma compañía, descuentos, contratos con permanencia, etc. Sin embargo, otra tarifa muy común es la tarifa regulada o también llamada PVPC. La tarifa PVPC es una tarifa regulada por el Gobierno de España que establece los precios de la electricidad para todo el territorio nacional. Se trata de un precio dinámico que va cambiando en cada hora del día y está indexado al mercado mayorista de electricidad. Las características principales de la tarifa PVPC son las siguientes [36] [37]: • Se pueden acoger a la tarifa PVPC personas físicas o microempresas, con tensiones no superiores a 1 kV y con potencia contratada menor o igual a 10 kW. • Se trata de un precio variable que va cambiando para cada hora del día y que depende de la oferta y demanda en el mercado eléctrico. • La tarifa PVPC solo puede ser comercializada por las denominadas comercializadoras de referencia [38]. Algunas de estas comercializadoras son Energía XXI (Endesa), Curenergía (Iberdrola) o
Control y monitorización mediante Node-RED 48 Comercializadora Regulada (Naturgy) [39]. • No tiene permanencia • Para acceder al Bono Social ofrecido por el Gobierno de España es necesario tener contratada la tarifa PVPC [40]. • De acuerdo a lo establecido en el Real Decreto 216/2014 [38], de 28 de marzo, por el que se establece la metodología de cálculo de los precios voluntarios para el pequeño consumidor de energía eléctrica y su régimen jurídico de contratación, la empresa Red Eléctrica de España, operadora del sistema eléctrico español [41], publica cada día a las 20.15 horas los precios horarios para el día siguiente [6]. En referencia al último punto, la empresa Red Eléctrica de España es la encargada de publicar cada día la información de precios de la tarifa PVPC. Dichos precios pueden consultarse en la página de precios PVPC proporcionada por la propia empresa, como puede verse en la figura 3-48 [42]: Figura 3-48. Consulta de precios de la tarifa PVPC en la página web de Red Eléctrica Además, Red Eléctrica de España ofrece una API REST llamada REData API [5] que permite la consulta de una amplia gama de datos relacionados con la red eléctrica española. Entre la información que se puede consultar destacan demanda en tiempo real, estructura de la generación eléctrica desglosada por tecnologías (solar, eólica, nuclear, etc), emisiones de CO2, o lo que más nos concierne, los precios de la tarifa PVPC. En la figura 3-49 se muestra un ejemplo de consulta a dicha API REST para obtener los precios de la tarifa PVPC para las 24 horas del día. Los precios proporcionados por el servicio se dan en €/MWh:
49 49 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-49. Consulta de precios de la tarifa PVPC en REData API La URL utilizada en dicha consulta es la siguiente: https://apidatos.ree.es/es/datos/mercados/preciosmercados-tiempo-real?start_date=2024-4-1T00:00&end_date=2024-4- 1T23:59&time_trunc=hour&geo_trunc=electric_system&geo_limit=peninsular&geo_ids=8741 . Para empezar, el recurso que queremos consultar se corresponde con la ruta /es/datos/mercados/preciosmercados-tiempo-real, que es la que nos proporciona la información de precios de la tarifa PVPC en tiempo real. Posteriormente, en el query string se deben proporcionar una serie de parámetros mostrados en la tabla 3- 3: Parámetro Significado start_date Fecha y hora de inicio en formato ISO 8601 end_date Fecha y hora de fin en formato ISO 8601 time_trunc Forma temporal de agrupar los datos. Para consultar la información de precios por hora su valor debe ser hour.
Control y monitorización mediante Node-RED 56 Figura 3-59. Representación gráfica del coste por hora y del coste total del día 3.11 Históricos de consumo y costes Gracias a los datos de consumo y costes que se han ido generando, puede resultar de interés generar registros históricos para que el usuario pueda llevar un seguimiento del consumo que ha ido teniendo y de los costes que le han supuesto esos consumos. Por simplicidad y para evitar saturar la base de datos con demasiada información, se almacenarán los consumos y costes totales del día. Es decir, cada día que pase habrá un registro nuevo en el histórico de consumo y otro en el histórico de costes.
57 57 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico 3.11.1 Almacenamiento de datos de consumo y costes Como se explicará en el Capítulo 4 (Servicio REST de consumo y costes), cada vez que se almacena una nueva medida de potencia, automáticamente se recalcula el consumo total del día con esa nueva información y se almacena en la base de datos. Sin embargo, en el caso del coste es necesario conocer los precios. Como decisión de diseño se ha decidido que el cálculo de los costes se realice desde NodeRED, y que posteriormente se almacene esa información mediante una ruta del servicio REST de consumo y costes. El flujo encargado de esta última tarea se muestra en la figura 3-60: Figura 3-60. Flujo NodeRED encargado de almacenar los datos de coste diario A partir del coste total del día proporcionado por la función costeTotalDia, la función actualizarCosteDiario construye un mensaje JSON con la fecha del día actual y el coste total. Este mensaje JSON se le pasará al nodo que se encarga de hacer la petición HTTP POST a la ruta /shelly-plug/costes del servicio REST de consumo y costes, para que almacene esta información en la base de datos. En el caso de que ya exista un valor de coste para ese día, en vez de crearse un nuevo registro se actualizará su valor en la base de datos. 3.11.2 Representación de los históricos El servicio REST implementado en este proyecto también nos proporciona rutas para obtener los históricos de consumos y de costes almacenados en la base de datos. En el caso del histórico de consumo, el flujo mostrado en la figura 3-61 se encarga de obtener este histórico y representarlo en la interfaz de usuario mediante una gráfica de barras: Figura 3-61. Flujo NodeRED encargado de obtener el histórico de consumo En este flujo se hace una petición HTTP GET a la ruta /shelly-plug/consumo/medidas para obtener las medidas de consumo diario almacenadas en la base de datos. A continuación, se utiliza la función prepararGraficaHistoricoConsumo para preparar los datos para que puedan ser representados en la gráfica
Control y monitorización mediante Node-RED 58 de barras que puede verse en la figura 3-62: Figura 3-62. Representación gráfica del histórico de consumo De forma análoga, mediante peticiones HTTP GET a la ruta /shelly-plug/costes, el flujo de la figura 3-63 nos permite obtener el histórico de costes y representarlo en la gráfica de barras de la figura 3-64: Figura 3-63. Flujo NodeRED encargado de obtener el histórico de costes
59 59 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-64. Representación gráfica del histórico de costes De forma resumida, los mensajes que se intercambian para la consulta de los históricos de consumo y costes pueden verse en la figura 3-65:
Control y monitorización mediante Node-RED 60 Figura 3-65. Diagrama de paso de mensajes para la consulta de históricos 3.12 Gestión de datos almacenados En la Sección 3.5 ya se comentó que las medidas de potencia son borradas de la base de datos tras finalizar el día, puesto que dejan de tener utilidad una vez que se ha calculado y almacenado el consumo y costes totales de ese día. No obstante, los flujos de la figura 3-66 sirven para que el usuario pueda borrar manualmente tanto las medidas de potencia como los históricos de consumo y costes almacenados en la base de datos:
61 61 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-66. Flujos NodeRED para la gestión de datos del sistema domótico Estos flujos crean los botones mostrados en la figura 3-67. Al pulsarlos, estos botones provocarán el envío de peticiones HTTP DELETE a las siguientes rutas: • Borrar medidas de potencia: /shelly-plug/potencia/medidas • Borrar consumos diarios: /shelly-plug/consumo/medidas • Borrar costes diarios: /shelly-plug/costes Figura 3-67. Botones para el borrado de datos de la base de datos De forma preventiva, antes de mandar la petición de borrado, se le muestra una notificación al usuario para confirmar que realmente desea borrar los datos correspondientes de la base de datos, como puede verse en la figura 3-68:
Control y monitorización mediante Node-RED 62 Figura 3-68. Notificación de confirmación de borrado de datos Tras el borrado de datos, al usuario se le informa de que los datos han sido borrados de forma satisfactoria mediante la notificación mostrada en la figura 3-69: Figura 3-69. Notificación para informar de que los datos han sido borrados con éxito 3.13 Interfaz de usuario 3.13.1 Creación de la interfaz Para la creación de la interfaz de usuario, se ha instalado el módulo node-red-dashboard [43]. Este módulo proporciona una serie de nodos de interfaz gráfica para la creación de botones, representación de series temporales, gráficas de barras, contadores, interruptores, envío de notificaciones, etc. Para instalar este módulo basta con ir a las opciones de NodeRED, seleccionar la opción Manage Palette, buscar el módulo e instalarlo. Una vez instalado, los nodos de este módulo estarán disponibles en el editor, como puede verse en las figuras 3-70 y 3-71:
63 63 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-70. Opción Manage Palette de NodeRED Figura 3-71. Nodos del módulo node-red-dashboard
Control y monitorización mediante Node-RED 64 Estos nodos se han utilizado para poder visualizar datos de forma muy sencilla y directa desde los propios flujos de NodeRED, evitando tener que desarrollar una interfaz externa. El módulo de dashboard permite organizar las páginas de la interfaz en lo que se denominan groups (grupos). Cada uno de los nodos de interfaz gráfica se pueden asociar a un grupo, de tal forma que luego se pueda editar la disposición de los elementos en la interfaz de usuario, como puede verse en la figura 3-72: Figura 3-72. Herramienta para la disposición de elementos en la interfaz de usuario 3.13.2 Página principal y navegación por la interfaz Al acceder a la interfaz de usuario, la página principal que se muestra es la de monitorización de consumo, la cual se explica en la Sección 3.13.3 (Monitorización). El aspecto de esta página principal puede verse en la figura 3-73:
65 65 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 3-73. Página principal de la interfaz de usuario Para navegar por las diferentes páginas de la interfaz, en la esquina superior izquierda hay un botón con tres rayas que permite seleccionar la página que quiere verse en la interfaz, como puede verse en la figura 3-74: Figura 3-74. Navegación por la interfaz de usuario Las páginas que forman la interfaz de usuario y que se explicarán a continuación son las siguientes:
Control y monitorización mediante Node-RED 72 Los botones de esta página permiten el borrado de medidas de potencia, consumos diarios, y costes diarios de la base de datos. La interacción con estos botones se muestra en la Sección 3.12 (Gestión de datos almacenados).
73 4 SERVICIO REST DE CONSUMO Y COSTES De forma conjunta a la implementación de los aspectos de control y monitorización de consumo eléctrico realizados mediante NodeRED, se ha desarrollado un servicio REST para facilitar el almacenamiento de las medidas de potencia proporcionadas por el enchufe inteligente. A partir de estos datos de potencia, este servicio REST es capaz de realizar una estimación del consumo eléctrico que se ha producido en un rango horario específico. Además, conforme se van almacenando medidas de potencia, el servicio REST va creando y actualizando registros de consumo de forma automática, lo cual facilita la creación de un histórico de consumo diario en la base de datos. Por otro lado, este servicio también permite almacenar los costes asociados al consumo energético, creando así un histórico de costes. De forma automática, desde NodeRED se hacen peticiones HTTP a las rutas de este servicio REST para monitorizar la potencia consumida en el enchufe, hacer un seguimiento del consumo eléctrico, y generar históricos de consumos y costes, así como recuperar esta información de la base de datos para poder visualizarla en la interfaz de usuario. Para la creación de este servicio, se ha desarrollado una aplicación Flask en la que se han implementado todas las funcionalidades comentadas anteriormente. Esta aplicación se ha encapsulado en una imagen Docker personalizada para poder desplegar el servicio junto al resto de contenedores del sistema utilizando Docker- Compose. 4.1 Despliegue y configuración de la base de datos Para el almacenamiento y gestión de los datos generados por el sistema domótico, el servicio REST de consumo y costes se apoya en el uso de una base de datos PostgreSQL. 4.1.1 Despliegue de la base de datos En la página de la imagen oficial de PostgreSQL [44] podemos encontrar una guía detallada de cómo crear contenedores con esta imagen utilizando comandos Docker o mediante Docker-Compose. En la figura 4-1 se muestra la definición del contenedor PostgreSQL realizada mediante Docker-Compose: Cada guerra es una destrucción del espíritu humano. - Henry Miller -
Servicio REST de consumo y costes 74 Figura 4-1. Definición del contenedor PostgreSQL en Docker-Compose La definición de este contenedor consiste en lo siguiente: • Crear un servicio en Docker-Compose llamado base_datos. • Crear un contenedor llamado postgresql, asociado al servicio base_datos. • Crear dicho contenedor a partir de la última versión de la imagen de PostgreSQL, indicado por la etiqueta latest. • Configurar las siguientes variables de entorno: ▪ POSTGRES_USER: Usuario que queremos crear en PostgreSQL. ▪ POSTGRES_PASSWORD: Contraseña del usuario que queremos crear. ▪ POSTGRES_DB: Nombre de la base de datos que se creará automáticamente al crear el contenedor, en este caso, monitor_consumo. ▪ PG_DATA: Directorio del contenedor en el que PostgreSQL almacenará los datos, que en este caso es /var/lib/postgresql/data/pgdata. ▪ TZ: Zona horaria del contenedor, que en este caso es la de Madrid. • Abrir el puerto 5432 de la máquina anfitriona y redirigirlo al puerto 5432 del contenedor, que es el puerto por defecto utilizado por PostgreSQL. • Reiniciar automáticamente el contenedor en caso de que se detenga, garantizando que el servicio se esté ejecutando en todo momento. • Compartir el directorio ./postgresql/data del host (partiendo del directorio de trabajo donde está el fichero docker-compose.yaml) con el directorio /var/lib/postgresql/data del contenedor. De esta forma podemos persistir la información de la base de datos en la máquina anfitriona, aunque borremos el contenedor. 4.1.2 Creación de las tablas en la base de datos Una vez que hayamos desplegado la base de datos utilizando Docker-Compose, podemos crear las tablas en la base de datos mediante un script Bash llamado base_datos.sh. El contenido de dicho script se muestra en la figura 4-2:
75 75 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 4-2. Contenido del fichero base_datos.sh En este script nos conectamos a la base de datos monitor_consumo y ejecutamos las sentencias SQL del fichero crear_tablas.sql. En la figura 4-3 pueden verse las sentencias SQL incluidas en este fichero: Figura 4-3. Contenido del fichero crear_tablas.sql Mediante este fichero SQL creamos las siguientes tablas: • potencia_shelly: En esta tabla es donde almacenamos las medidas de potencia generadas por el Shelly Plug. Cada medida de potencia tiene un identificador único (id_medida), la fecha y hora en la que se tomó esa medida (fecha_medida), y el valor de potencia en vatios (potencia). • consumo_shelly: Esta tabla sirve para almacenar el histórico de consumo. Cada medida de consumo tiene un identificador único (id_medida), la fecha en la que se obtuvo esa medida (fecha_medida), y el valor de consumo en vatios-hora (consumo). • coste_shelly: Es la tabla en la que almacenamos el histórico de costes. Cada registro de coste tiene un identificador único (id_coste), la fecha en la que se calculó ese coste (fecha_coste), y el valor del coste en euros (coste). 4.2 Rutas del servicio REST En esta sección es donde presentamos las rutas del servicio REST de consumo y costes, es decir, aquellos puntos de acceso que nos permiten interactuar con los recursos ofrecidos por el servicio. Para ello, haremos
Servicio REST de consumo y costes 76 uso de la interfaz Swagger que se ha generado para la documentación del servicio REST (ver Sección 4.5 Documentación OpenAPI mediante Flasgger). Gracias a esta interfaz, podemos hacer peticiones HTTP a las rutas del servicio REST y visualizar las respuestas del servidor de forma sencilla. En la figura 4-4 se muestra una imagen de la documentación OpenAPI del servicio REST y en la tabla 4-1 se hace una descripción de cada ruta y los métodos HTTP que soportan: Figura 4-4. Especificación OpenAPI del servicio REST de consumo y costes Ruta Métodos HTTP Descripción /ping GET Ruta para probar el funcionamiento del servicio. El servidor responderá con el mensaje “pong!” como confirmación de que el servicio está operativo. /shelly-plug/potencia/medidas GET, POST, DELETE Ruta que permite interactuar con las medidas de potencia (en vatios) del Shelly Plug según el método HTTP utilizado: • GET: Permite obtener las medidas de potencia del Shelly Plug en un intervalo horario especificado en el query string de la petición. En caso de no especificarse, se obtienen las medidas de la última hora. • POST: Permite añadir una nueva
77 77 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico medida de potencia en la base de datos. • DELETE: Permite eliminar todas las medidas de potencia de la base de datos o una medida específica según su identificador. /shelly-plug/consumo GET Ruta para obtener el consumo energético (en vatios-hora) en un intervalo horario especificado en el query string de la petición. En caso de no especificarse, se obtiene el consumo de la última hora. El cálculo del consumo se realiza a partir de las medidas de potencia almacenadas en la base de datos. /shelly-plug/consumo/consumopor-hora GET Ruta para obtener el consumo energético (en vatios-hora) en cada una de las 24 horas del día. /shelly-plug/consumo/medidas GET, DELETE Ruta para interactuar con el histórico de medidas de consumo energético (en vatioshora) según el método HTTP utilizado: • GET: Permite obtener las medidas de consumo almacenadas en la base de datos. • DELETE: Permite eliminar todas las medidas de consumo de la base de datos. /shelly-plug/costes GET, POST, DELETE Ruta para interactuar con el histórico de costes de consumo energético (en euros) según el método HTTP utilizado: • GET: Permite obtener todos los registros de costes de consumo almacenados en la base de datos. • POST: Permite almacenar un nuevo registro de coste energético o actualizar uno ya existente. • DELETE: Permite eliminar todos los registros de coste energético de la base de datos. Tabla 4-1. Rutas del servicio REST de consumo y costes Como se comentó en el Capítulo 3 (Control y monitorización mediante NodeRED), NodeRED realiza peticiones HTTP a las rutas de este servicio REST para monitorizar la potencia instantánea consumida en el enchufe, hacer un seguimiento del consumo eléctrico, y generar históricos de consumos y costes. Como puede verse en la especificación OpenAPI del servicio mostrada en la figura 4-4, las rutas están organizadas según el grupo de recursos con el que se interactúa: test, potencia, consumo y coste. La implementación de las funciones que manejan estas rutas se encuentra en el fichero rutas.py de la aplicación Flask. En las siguientes secciones se presentarán ejemplos de uso de estas rutas.
Servicio REST de consumo y costes 78 4.2.1 Test La única ruta de este grupo es /ping, la cual simplemente sirve para probar el funcionamiento del servicio REST. Si realizamos una petición GET a esta ruta, el servidor nos responderá con un objeto JSON que contiene el mensaje “pong!”, como puede verse en la figura 4-5: Figura 4-5. Petición GET a /ping A modo de ejemplo, en la figura 4-6 se muestra un extracto del fichero rutas.py con el código de la función que maneja las peticiones GET a esta ruta. Cada combinación de rutas y métodos HTTP mostradas en la figura 4-4 tiene asociada una función de la aplicación Flask que maneja esas peticiones y devuelve la respuesta correspondiente. Figura 4-6. Código de la función ping en rutas.py 4.2.2 Potencia Este grupo de recursos tiene una única ruta: /shelly-plug/potencia/medidas, con la que se puede interactuar con los métodos GET, POST y DELETE.
79 79 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Si realizamos una petición GET a esta ruta sin ningún parámetro en el query string, obtendremos una lista con las medidas de potencia (en vatios) registradas en la última hora, como puede verse en la figura 4-7: Figura 4-7. Petición GET a /shelly-plug/potencia/medidas (sin parámetros) Sin embargo, en el query string podemos especificar que queremos obtener las medidas de potencia que se registraron desde una hora inicio a una hora fin. Por ejemplo, en la figura 4-8 puede verse como se obtienen las medidas registradas desde las 11:00 hasta las 11:02:
Servicio REST de consumo y costes 80 Figura 4-8. Petición GET a /shelly-plug/potencia/medidas (con parámetros) Mediante peticiones POST, podemos insertar nuevas medidas de potencia en la base de datos a partir de objetos JSON que contienen la información de la medida, como puede verse en las figuras 4-9 y 4-10:
81 81 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 4-9. Cuerpo de la petición POST a /shelly-plug/potencia/medidas Figura 4-10. Petición POST a /shelly-plug/potencia/medidas Finalmente, mediante peticiones DELETE podemos borrar una medida específica de la base de datos si también especificamos su identificador, como se muestra en la figura 4-11, o si no lo indicamos, podemos borrar todas las medidas de la base de datos, como puede verse en la figura 4-12:
Servicio REST de consumo y costes 88 En cambio, mediante peticiones POST, podemos insertar un nuevo registro de coste o actualizar uno ya existente a partir de objetos JSON que contienen la información de dicho coste, como puede verse en las figuras 4-19 y 4-20: Figura 4-19. Cuerpo de la petición POST a /shelly-plug/costes Figura 4-20. Petición POST a /shelly-plug/costes
89 89 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Finalmente, mediante peticiones DELETE podemos borrar todo el histórico de costes de la base de datos, como se muestra en la figura 4-21: Figura 4-21. Petición DELETE a /shelly-plug/costes 4.3 Cálculo del consumo eléctrico En esta sección es donde se explica la metodología que se ha seguido para calcular el consumo eléctrico a partir de las medidas de potencia generadas por el Shelly Plug. Para poder calcular el consumo, primero se ha definido una función dentro del fichero utilidades.py llamada calcula_consumo. Además, este fichero contiene otras funciones auxiliares que nos permiten realizar conexiones con la base de datos y transformar objetos de la clase MedidaPotencia (ver Sección 4.4 Modelo de datos) a diccionarios, para facilitar su posterior conversión a objetos JSON. El código de la función calcula_consumo se muestra en la figura 4-22: Figura 4-22. Código de la función calcula_consumo en utilidades.py
Servicio REST de consumo y costes 90 Esta función recibe una lista de diccionarios en la que cada uno de ellos es una medida de potencia. Cada medida de potencia tiene un identificador único, la fecha y hora en la que se tomó la medida, y el valor de potencia que se registró (en vatios). De forma general, el consumo eléctrico (o energía) se calcula como la integral de la potencia eléctrica instantánea en un intervalo de tiempo. Sin embargo, a partir de los mensajes de potencia provenientes del Shelly Plug, estamos muestreando valores de potencia cada 30 segundos. Si consideramos que la potencia instantánea no cambia de forma significativa entre dos medidas de potencia consecutivas, podemos aproximar la integral a un sumatorio de valores de potencia multiplicados por el intervalo de tiempo hasta la siguiente medida. La fórmula empleada para este cálculo se muestra en la figura 4-23: 𝐸=∫ 𝑝(𝑡) 𝑑𝑡≈∑𝑝𝑖∗ 𝑁−1 𝑖=1 𝑡2 𝑡1∆𝑡𝑖 Figura 4-23. Fórmula para la estimación del consumo eléctrico Donde: • 𝐸 es el consumo eléctrico. • 𝑝𝑖 es el valor de potencia de la medida 𝑖. • ∆𝑡𝑖 es el intervalo de tiempo entre las medidas 𝑖 e 𝑖+1. • 𝑁 es el número total de medidas de potencia. En esta fórmula, la última medida de potencia queda fuera del cálculo porque no es posible determinar cuál será el intervalo de tiempo hasta la próxima medida. Además, cuando este intervalo de tiempo es superior al minuto, la medida tampoco se incluye en el cálculo. El motivo de esto es que intervalos de tiempo muy superiores al minuto pueden deberse a pérdidas de conexión con el Shelly Plug, a la parada y posterior rearranque del sistema domótico, o a la desconexión del Shelly Plug de la toma de corriente. Por lo tanto, incluir esa medida de potencia en el cálculo podría hacer que perdamos precisión en la estimación del consumo, ya que conforme mayor sea ese tiempo, es menos probable que la potencia se haya mantenido constante. La función mostrada en la figura 4-22 implementa esta fórmula para calcular el consumo eléctrico a partir de las medidas de potencia proporcionadas como parámetro. Además, se realizan las conversiones de unidades necesarias para devolver el resultado de consumo eléctrico en vatios-hora. Como ejemplo de uso de esta función, en la figura 4-24 se muestra un extracto de la función obtener_consumo dentro del fichero rutas.py que procesa las peticiones GET a la ruta /shelly-plug/consumo cuando queremos obtener el consumo eléctrico que se ha producido entre una hora inicio y una hora fin:
91 91 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 4-24. Extracto de la función obtener_consumo en rutas.py En este fragmento de código, obtenemos las horas de inicio y fin a partir de los parámetros del query string de la petición HTTP. Adicionalmente, necesitaremos construir objetos de tipo fecha (datetime) para poder obtener de la base de datos aquellas medidas que estén en el intervalo horario que queremos. Para ello, combinamos la fecha del día actual con las horas proporcionadas. Posteriormente, nos conectamos a la base de datos y realizamos la consulta de las medidas de potencia deseadas. Luego, creamos una lista de medidas de potencia (convirtiendo previamente los objetos de la clase MedidaPotencia a diccionarios), y calculamos el consumo energético llamando a la función calcula_consumo. Además, a diferencia del histórico de costes, que se generaba a partir de peticiones POST a la ruta /shellyplug/costes, como decisión de diseño se ha decidido que el histórico de consumo lo actualice automáticamente el servicio REST cada vez que se inserta una nueva medida de potencia en la base de datos. Podemos ver esto ilustrado en las figuras 4-25 y 4-26, que muestran parte del código de la función nueva_medida_potencia dentro del fichero rutas.py, que maneja las peticiones POST que se hacen a la ruta /shellyplug/potencia/medidas:
Servicio REST de consumo y costes 92 Figura 4-25. Extracto de la función nueva_medida_potencia en rutas.py. Parte 1
93 93 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 4-26. Extracto de la función nueva_medida_potencia en rutas.py. Parte 2 En esta función, primero verificamos que el objeto JSON proporcionado en la petición tiene todos los atributos necesarios de una medida de potencia (fecha de la medida y valor de potencia). Luego, nos conectamos a la base de datos, creamos un objeto de la clase MedidaPotencia, y lo añadimos a la base de datos. A continuación, actualizamos el consumo del día de hoy. Para ello, obtenemos de la base de datos todas las medidas de potencia realizadas en el día actual, calculamos el consumo energético, y actualizamos el valor de consumo en la base de datos. Si no existía un registro de consumo para el día de hoy, creamos un objeto de la clase MedidaConsumo (ver Sección 4.4 Modelo de datos) y lo persistimos en la base de datos. De esta forma, el consumo del día actual se irá actualizando conforme se vayan obteniendo medidas de potencia, y cuando llegue el día siguiente, se creará un nuevo registro de consumo en la base de datos. 4.4 Modelo de datos Como se comentó en la Sección 2.2.6 (SQLAlchemy), la librería SQLAlchemy nos permite interactuar con bases de datos relacionales mediante programación orientada a objetos, sin necesidad de utilizar directamente sentencias SQL. El fichero modelos.py contiene la definición de las clases ORM que nos permiten interactuar con las tablas explicadas en la Sección 4.1.2 (Creación de las tablas en la base de datos) siguiendo este enfoque. El contenido de este fichero se muestra en la figura 4-27:
Servicio REST de consumo y costes 94 Figura 4-27. Contenido del fichero modelos.py En este fichero se definen tres clases ORM: • MedidaPotencia: Relacionada con la tabla potencia_shelly. • MedidaConsumo: Relacionada con la tabla consumo_shelly. • Coste: Relacionada con la tabla coste_shelly. 4.5 Documentación OpenAPI mediante Flasgger Para crear la documentación del servicio REST, se ha hecho uso de Flasgger [15], una extensión de Flask que permite realizar especificaciones OpenAPI interactivas de forma automática. En la Sección 4.2 (Rutas del servicio REST) ya se presentaron las rutas implementadas en este servicio, y se mostraron ejemplos de uso de dichas rutas gracias a la interfaz Swagger que nos proporciona Flasgger. Esta interfaz nos permite interactuar directamente con el servicio REST sin necesidad de realizar las peticiones HTTP GET, POST, PUT y DELETE utilizando las herramientas avanzadas del navegador o usando herramientas externas como Curl o Postman. El fichero __init__.py, que sirve para indicar que el directorio app con la aplicación Flask es un paquete Python, define una función llamada create_app que nos permite crear instancias de la aplicación Flask desarrollada. Además, en esta función es donde realizamos la configuración de Flassger, especificando la versión de Swagger que queremos utilizar, y la descripción y versión del servicio REST desarrollado. En la figura 4-28 se muestra el contenido del fichero __init__.py:
95 95 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Figura 4-28. Contenido del fichero __init__.py Para realizar la documentación de la API utilizando Flassger, en las funciones de la aplicación Flask que manejan las rutas del servicio REST, debemos escribir comentarios en formato YAML con la información que queramos especificar sobre la ruta. En la figura 4-29 se muestran los comentarios en formato YAML utilizados para documentar la ruta /shelly-plug/potencia/medidas atendiendo a peticiones GET: Figura 4-29. Ejemplos de comentarios Flassger para documentar las rutas del servicio REST En estos comentarios podemos hacer una descripción de la funcionalidad que nos ofrece la ruta, los parámetros que recibe, establecer etiquetas para organizar las rutas en distintos grupos, o especificar las respuestas del
Servicio REST de consumo y costes 96 servidor. Tras documentar todas las rutas implementadas, Flassger generará de forma automática la documentación OpenAPI al lanzar la aplicación Flask. Para visualizar esta documentación, tenemos que acceder a la ruta /apidocs del servicio REST, como puede verse en la figura 4-30: Figura 4-30. Acceso a la interfaz Swagger del servicio REST Esta interfaz Swagger también permite interactuar con cada una de las rutas documentadas mediante el botón “Try it out”. Además, si en los comentarios de las funciones de la aplicación Flask hemos especificado los parámetros de la ruta y su formato, podemos hacer peticiones más complejas que nos permiten probar el servicio REST de forma más completa, como puede verse en la figura 4-31: Figura 4-31. Interacción con las rutas del servicio REST mediante Swagger
97 97 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico 4.6 Pruebas de integración del servicio REST Para las pruebas de integración del servicio REST se ha utilizado Pytest [18], un framework de Python que nos permite realizar pruebas unitarias, de integración y funcionales de una aplicación Python. Para ello, se ha desarrollado un script Bash llamado pruebas.sh, que se encarga de crear una base de datos de pruebas en el contenedor PostgreSQL, crear las tablas y poblarlas de datos mediante el fichero tablas_tests.sql, ejecutar las pruebas con Pytest, y borrar la base de datos de pruebas. El contenido del fichero pruebas.sh se muestra en la figura 4-32: Figura 4-32. Contenido del fichero pruebas.sh El contenido del fichero tablas_tests.sql es el mismo que el del fichero crear_tablas.sql de la figura 4-3, pero además incluimos sentencias para insertar datos de ejemplo para poder realizar las pruebas del servicio REST, como puede verse en la figura 4-33: Figura 4-33. Inserción de datos de ejemplo en tablas_tests.sql
105 5 DESPLIEGUE DEL SISTEMA EN MICROSOFT AZURE En este capítulo es donde explicamos el proceso de despliegue del sistema domótico en una máquina virtual en la nube de Microsoft Azure, así como aspectos de operación del sistema realizados mediante Docker- Compose. Entre otras opciones disponibles, como Amazon Web Services o Google Cloud Platform, se ha elegido Azure por las facilidades que ofrece en el despliegue y gestión de máquinas virtuales, y por los acuerdos alcanzados entre la Universidad de Sevilla y Microsoft, que permiten a los estudiantes utilizar estos servicios de forma gratuita gracias a la licencia Azure for Students. 5.1 Creación de la máquina virtual en Azure Una vez que hayamos activado nuestra cuenta de estudiante [45], en el portal de Azure [46] tendremos disponible un panel de control que nos permitirá acceder a los distintos servicios ofrecidos por la plataforma, así como información acerca de nuestros recursos, suscripciones, facturación, monitorización, seguridad, etc. En la figura 5-1 se muestra una imagen del panel de control del portal de Azure: Las grandes oportunidades nacen de haber sabido aprovechar las pequeñas. - Bill Gates -
Despliegue del sistema en Microsoft Azure 106 Figura 5-1. Panel de control del portal de Azure Para crear un nuevo recurso basta con seleccionar la opción “Crear un recurso” y elegir el tipo de servicio de que deseamos, como puede verse en la figura 5-2. Entre las opciones disponibles está la creación de máquinas virtuales, aplicaciones web, servidores Windows o Linux, bases de datos, herramientas de inteligencia artificial, contenedores, etc. En nuestro caso, seleccionaremos la opción de crear una máquina virtual. Figura 5-2. Servicios ofrecidos por Azure
107 107 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Tras seleccionar dicha opción, se nos mostrarán las opciones de creación de la máquina virtual, tal como se muestra en la figura 5-3. En estas opciones, debemos especificar el tipo de suscripción que tenemos (en nuestro caso, Azure for Students), el nombre que le daremos a la máquina virtual, la región en la que queremos desplegarla, el sistema operativo, el número de CPUs, la cantidad de memoria, y el almacenamiento, entre otras configuraciones. Además, al configurar el usuario administrador, podemos generar un par de claves SSH para conectarnos de forma remota a la máquina virtual sin necesidad de configurar una contraseña. Figura 5-3. Opciones de creación de una máquina virtual en Azure Una vez creada, en los recursos del portal de Azure mostrados en la figura 5-1 aparecerá nuestra máquina virtual. Al seleccionarla, se abrirá una nueva ventana en la que podremos ver información sobre la máquina virtual y realizar acciones sobre ella, como iniciarla, detenerla o reiniciarla a través de los botones disponibles, como podemos ver en la figura 5-4. Además, se nos ofrece una amplia gama de opciones que nos permiten monitorizar el uso de recursos de la máquina virtual, conocer detalles de facturación por horas de uso, realizar backups, y configurar las reglas de entrada y salida del firewall, entre otras funcionalidades.
Despliegue del sistema en Microsoft Azure 108 Figura 5-4. Detalles de la máquina virtual creada en Azure Para este proyecto, se ha creado una máquina virtual llamada domotica con sistema operativo Ubuntu 20.04, una CPU virtual, 1 GB de RAM, 30 GB de almacenamiento, y se le ha asignado la IP pública 20.250.161.128. Además, para poder utilizar la interfaz de usuario del sistema domótico y que el enchufe inteligente pueda publicar las medidas de potencia en el broker MQTT, debemos añadir nuevas reglas de entrada en el firewall de la máquina virtual. Para ello, accedemos a la sección “Redes” y añadimos las reglas mostradas en la figura 5-5. Estas reglas permiten conexiones entrantes por el puerto 22 para poder conectarnos a la máquina mediante SSH, así como por los puertos 443 y 1883 para aceptar tráfico HTTPS y MQTT, respectivamente. Figura 5-5. Reglas de entrada del firewall de la máquina virtual 5.2 Despliegue y operación del sistema domótico Una vez que la máquina virtual esté operativa, para desplegar el sistema domótico podemos conectarnos mediante SSH y clonar el repositorio GitHub del proyecto, que se encuentra disponible en el siguiente enlace: https://github.com/sergarlop2/TFG
109 109 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Tras clonar el repositorio, en el directorio TFG/docker encontraremos el fichero docker-compose.yaml, que nos permitirá crear y gestionar los contenedores del sistema domótico utilizando Docker-Compose, como podemos ver en la figura 5-6: Figura 5-6. Ficheros del directorio TFG/docker Para arrancar el sistema domótico nos situamos en el directorio en el que está el fichero docker-compose.yaml y ejecutamos el comando “docker compose up”. De forma alternativa, podemos ejecutar el comando con la opción “-d” para ejecutar los contenedores en segundo plano, como podemos ver en la figura 5-7: Figura 5-7. Arranque del sistema domótico utilizando Docker-Compose Si es la primera vez que arrancamos el sistema domótico, debemos ejecutar el script base_datos.sh explicado en la Sección 4.1.2 (Creación de las tablas en la base de datos) para crear las tablas en la base de datos del contenedor PostgreSQL. En posteriores rearranques esto no será necesario, ya que la información de la base de datos del contenedor se persiste en el sistema de ficheros de la máquina anfitriona, como se explicó en la Sección 4.1.1 (Despliegue de la base de datos). Por otro lado, no será necesario modificar la configuración del servicio REST ni la de los nodos de NodeRED, ya que a pesar de que el sistema está desplegado en un nuevo entorno en el que las direcciones IP de los contenedores o de la máquina anfitriona pueden ser diferentes, al utilizar el servicio DNS interno de Docker Compose no tenemos que hacer ningún cambio, y podemos reutilizar la configuración usada en el entorno de desarrollo. Tras poner en funcionamiento el sistema domótico, al navegar a la dirección https://20.250.161.128/, tendremos acceso a la interfaz de usuario de NodeRED de forma totalmente remota, como podemos ver en la figura 5-8:
Despliegue del sistema en Microsoft Azure 110 Figura 5-8. Acceso a la interfaz de usuario de NodeRED de forma remota Además, Docker-Compose proporciona una gran cantidad de comandos que pueden ser de gran utilidad a la hora de operar y monitorizar los contenedores del sistema. Por ejemplo, en la figura 5-9 se muestra el uso del comando “docker compose logs”, que nos permite ver los logs generados por cada uno de los contenedores que tenemos desplegados: Figura 5-9. Consulta de los logs de los contenedores utilizando Docker Compose Finalmente, para reiniciar el sistema domótico podemos usar el comando “docker compose restart”, y para detenerlo podemos usar “docker compose stop”, como podemos ver en la figura 5-10: Figura 5-10. Reinicio y parada del sistema domótico utilizando Docker Compose
111 6 CONCLUSIONES Y LÍNEAS FUTURAS Como capítulo final de esta memoria, haremos una reflexión acerca de los objetivos que se han alcanzado tras la finalización del proyecto, destacando las lecciones aprendidas durante todo el proceso de investigación, diseño y desarrollo, así como las dificultades que se han ido encontrando y cómo se han superado. Además, en base a los resultados y las experiencias obtenidas, exploraremos una serie de líneas futuras que permitirán mejorar y ampliar el sistema domótico presentado en este Trabajo Fin de Grado. 6.1 Conclusiones y lecciones aprendidas Tras la realización de este proyecto, podemos afirmar que se han alcanzado todos los objetivos que se propusieron al comienzo de este. Como resultado, se ha conseguido desarrollar un sistema domótico de control y monitorización del consumo eléctrico que cumple con una serie de funcionalidades atractivas para aquellas personas que quieran tener un mayor control acerca de su consumo y de los costes correspondientes. Considero que no solo se han conseguido los objetivos marcados desde el punto de vista académico, sino que se ha construido un sistema que aporta valor a todos aquellos consumidores que tienen contratada la tarifa regulada PVPC, y que a partir de este proyecto podría desarrollarse un producto que fuera competitivo en el mercado. La elección de NodeRED como nodo central de la arquitectura ha sido uno de los mayores éxitos de este proyecto, no solo por su capacidad de automatización de procesos e interconexión con distintas entidades, sino por el amplio grado de aplicación que tiene esta herramienta, que cada vez se va utilizando más en todo tipo de proyectos relacionados con el IoT y la domótica. Para mí ha supuesto un reto aprender esta nueva tecnología, puesto que está basada en un paradigma de programación totalmente distinto al que estoy acostumbrado, pero considero que todo este esfuerzo ha merecido la pena, porque probablemente me será de gran utilidad en el mundo laboral. Por otro lado, considero que otra buena decisión fue la de realizar la interfaz de usuario desde el propio NodeRED. Su rapidez de creación, así como la gran cantidad de elementos gráficos que ofrece para la visualización de datos, y su fácil integración en los flujos de NodeRED, me han permitido crear una interfaz intuitiva, estética y muy apropiada para el tipo de problema que se está resolviendo. De otra manera, por ejemplo realizando una aplicación móvil, habría tardado mucho más en crear la interfaz, y probablemente me habrían surgido una gran cantidad de problemas a la hora de intentar integrarla con el resto del sistema. La decisión de diseño de crear un servicio REST para el almacenamiento y gestión de los datos producidos por el sistema domótico fue otro gran acierto. En un principio consideré que desde el propio NodeRED podría ser El mundo que hemos creado es un proceso de nuestro pensamiento. No se puede cambiar sin cambiar nuestra forma de pensar. - Albert Einstein -
Conclusiones y líneas futuras 112 capaz de realizar todas estas tareas de persistencia, puesto que existen módulos en NodeRED que permiten la conexión e interacción con bases de datos. Sin embargo, una de las virtudes de NodeRED, que es la simplicidad de su programación mediante la configuración y conexión de elementos gráficos, es a su vez un defecto a la hora de implementar estas funcionalidades avanzadas, puesto que la complejidad y dificultad de depuración crece de forma exponencial. NodeRED resulta de gran utilidad a la hora de manejar flujos de datos e interconectar sistemas, pero no es la herramienta más adecuada para implementar funcionalidades más complejas, teniendo que recurrir por lo tanto a un lenguaje de programación tradicional. No obstante, esto ha supuesto una oportunidad para profundizar mis conocimientos sobre la implementación de servicios REST, y de forma más concreta, para aprender más en el desarrollo de proyectos Flask. Enfrentarme a la implementación de un servicio de este tipo de complejidad me ha permitido aprender mucho, no solo desde el punto de vista de la codificación, sino también en el diseño, documentación y realización de pruebas. Por otro lado, considero que la interacción del sistema domótico con otros sistemas externos, que en este caso es el servicio REST de Red Eléctrica, aporta un gran valor al proyecto. Durante el proceso encontré una buena cantidad de dificultades a la hora de manejar su API, realizar peticiones y procesar las respuestas, pero la inclusión de toda la información de precios y costes de la electricidad en el sistema final añade un gran atractivo al proyecto, justificando todo ese esfuerzo. Otra de las virtudes del proyecto ha sido haber planteado la arquitectura del sistema en microservicios y haber utilizado contenedores Docker desde el comienzo de la implementación. Con este enfoque, se han identificado cuáles debían ser los componentes fundamentales del sistema, y se ha realizado la correspondiente separación de responsabilidades, pensando además en aspectos de portabilidad durante el proceso de implementación. Este factor, junto a las ventajas de virtualización de Docker, ha simplificado el despliegue del sistema final en la nube de Azure, minimizando al máximo las diferencias entre el entorno de desarrollo y el de producción. De igual manera, el uso de Docker-Compose ha facilitado enormemente la operación coordinada de los servicios del sistema domótico. Además, haber desplegado el sistema final en la nube en vez de haberlo mantenido en la red local del hogar no solo permite el acceso remoto a la interfaz de usuario desde cualquier ubicación, sino que también abre la posibilidad de instalar el enchufe en diversas localizaciones. Este despliegue también me ha servido para aprender más acerca de la nube, aplicando dichos conocimientos para el caso particular de Azure. Finalmente, este proyecto me ha permitido adquirir nuevos conocimientos en los campos de la domótica y el IoT, desde el uso de protocolos como MQTT para interconectar dispositivos y sistemas, hasta aspectos de automatización, control, monitorización y gestión de los datos producidos en este tipo de entornos. 6.2 Líneas futuras En base a los resultados y experiencias obtenidos del proyecto, a continuación, enumeramos los distintos aspectos que podrían mejorarse, así como nuevas funcionalidades o ampliaciones del sistema domótico: • Posibilidad de añadir nuevos enchufes: Actualmente, solo se realiza la monitorización y control del consumo medido en un único enchufe. No obstante, para ampliar el sistema, se podría considerar la inclusión de nuevos enchufes. Para ello, sería necesario crear un formulario que registre tanto el identificador del enchufe como los tópicos MQTT utilizados por el dispositivo, permitiendo así realizar un control y seguimiento de los enchufes de forma independiente. Además, también se podría registrar cualquier otra información relevante, como localización, modelo, potencia máxima admitida, fecha de instalación, etc. • Ampliación a nuevos dispositivos domóticos: En concordancia con el punto anterior, el sistema podría expandirse no solo a enchufes inteligentes, sino a cualquier tipo de dispositivo domótico que permita su control a través de MQTT o que proporcione información sobre su estado y funcionamiento a través de este protocolo. • Mejora de la seguridad en las comunicaciones MQTT: El enchufe Shelly Plug S utilizado en el sistema no permite utilizar ningún mecanismo de cifrado en las comunicaciones realizadas mediante MQTT. Por lo tanto, en el broker Mosquitto no se ha podido configurar el uso del protocolo TLS, lo
113 113 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico cual es una deficiencia de seguridad que se debe a estas limitaciones en el hardware. Sin embargo, es probable que los nuevos modelos del Shelly Plug incluyan soporte para TLS. Además, podría considerarse la configuración del control de acceso al broker mediante usuario y contraseña, pero nuevamente este es un aspecto que depende de que el hardware admita estas funcionalidades. • Mejora de la seguridad en NodeRED: Tal y como está planteado el sistema, buena parte de su seguridad depende de los mecanismos ofrecidos por NodeRED, que en algunos casos pueden ser limitados. A pesar de que se ha configurado el uso de HTTPS y de que el acceso al editor de NodeRED está protegido mediante usuario y contraseña, podría añadirse autenticación en la interfaz de usuario. Para ello, lo más conveniente sería utilizar algún tipo de proxy inverso, como por ejemplo Nginx, que se encargue de la autenticación y pueda implementar mecanismos de seguridad más avanzados que los de NodeRED. • Control automático del enchufe en función de los precios de la electricidad: Gracias a la información de precios de la electricidad obtenida del servicio REST de Red Eléctrica, podría programarse un algoritmo en NodeRED que encendiera y apagara el enchufe de forma automática en función de unos umbrales de coste configurados por el usuario. • Añadir reglas de control personalizadas: Continuando con la idea del punto anterior, podría implementarse algún mecanismo para añadir reglas de control personalizadas, por ejemplo, para encender el enchufe en determinadas horas del día y apagarlo en las horas en las que no se requiera el consumo de energía. • Añadir filtros en la interfaz para mejorar la visualización de datos: Actualmente, en los históricos de consumo y costes solo es posible visualizar los datos organizados en días, obteniendo además todos los registros del histórico en cada consulta. Por lo tanto, en la interfaz de usuario se podría implementar una función de filtrado que permita, por ejemplo, obtener los datos de un mes específico, y desglosar los datos en días, semanas o meses, según lo indique el usuario. • Análisis de los datos registrados por el sistema: A partir de los datos registrados por el sistema, podrían generarse estadísticas tales como consumo medio, mínimo y máximo, análisis de periodicidad, correlación de los datos, detección de anomalías, etc. Además, mediante técnicas de inteligencia artificial, se podrían detectar tendencias y patrones de consumo, e incluso realizar predicciones sobre el consumo futuro de los usuarios. • Mejor gestión de los datos almacenados: Se podrían añadir nuevas opciones de borrado y actualización de los datos almacenados en el sistema. Por ejemplo, actualizar y borrar registros de días específicos, borrar datos a partir de una cierta fecha de antigüedad, o borrar datos de rangos de fechas personalizados. • Uso de DNS para la máquina virtual: Se podría asociar un nombre de dominio a la IP pública de la máquina virtual para facilitar la navegación a la interfaz de usuario de NodeRED. Para ello, se podrían utilizar servicios gratuitos de DNS dinámico, como DuckDNS, u optar por opciones de pago ofrecidas por el propio Azure o por registradores de dominios. • Uso de certificados digitales válidos en NodeRED: Para poder utilizar HTTPS en la interfaz de usuario de NodeRED, se ha generado un certificado x509 autofirmado que no está reconocido por ninguna CA, y por lo tanto, al acceder a la interfaz mediante un navegador aparece un aviso de seguridad. Para solucionar esto, podríamos obtener un certificado de forma gratuita mediante plataformas como Let’s Encrypt u obtenerlo de proveedores de certificados de pago.
Anexo A: Simulación del enchufe inteligente 120 Figura A-2: Contenido del fichero sim_enchufe.py. Parte 2 Para comenzar la simulación, debemos ejecutar el comando “python3 sim_enchufe.py”. Por defecto, en la simulación el enchufe estará en el estado “encendido”, y comenzará a publicar medidas de potencia de la misma forma que haría el enchufe real, como podemos ver en la figura A-3: Figura A-3: Ejecución de la simulación del enchufe inteligente
121 121 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico Además, de forma periódica se irá publicando el estado del enchufe (encendido o apagado) en el broker MQTT, lo cual nos permitirá hacer el seguimiento del estado desde la interfaz de usuario de NodeRED de la misma forma que haríamos con el enchufe real. De igual manera, podemos seguir enviando comandos de apagado y encendido desde la interfaz de usuario. Al apagar el enchufe, esto se verá reflejado en la simulación haciendo que la potencia publicada por el enchufe sea de cero vatios, y al encenderse volverán a publicarse valores aleatorios de potencia, como se muestra en la figura A-4: Figura A-4: Simulación del estado del enchufe mediante la recepción de comandos de control
Anexo A: Simulación del enchufe inteligente 122
123 123 Sistema domótico basado en NodeRED y servicio REST para el control y monitorización del consumo eléctrico ANEXO B: FICHERO DOCKER-COMPOSE.YAML Docker-Compose es la herramienta que nos ha permitido definir, configurar y desplegar los servicios del sistema domótico en contenedores Docker a partir de un fichero de configuración docker-compose.yaml. A lo largo de la memoria, se han ido mostrando extractos de este fichero y se ha explicado la definición de cada uno de los contenedores que encapsulan los servicios del sistema. En las figuras B-1 y B-2 se muestra el contenido completo del fichero docker-compose.yaml utilizado en el proyecto: Figura B-1: Contenido del fichero docker-compose.yaml. Parte 1
Anexo B: Fichero docker-compose.yaml 124 Figura B-2: Contenido del fichero docker-compose.yaml. Parte 2