El uso de AWS IoT para mejorar tu consumo eléctrico doméstico - Bootcamp Institute SAPI de CV

El uso de AWS IoT para mejorar tu consumo eléctrico doméstico

En este tutorial aprenderás más de Internet of Things, servicios de AWS y cómo aplicarlos para ahorrar en el costo y consumo de tus aparatos electrodomésticos, de manera fácil y sencilla. Con una explicación paso a paso.

¿Cuál es la diferencia entre IaaS, PaaS y SaaS? Leyendo El uso de AWS IoT para mejorar tu consumo eléctrico doméstico 16 minutos Siguiente ¿Data Analyst, Data Scientist o Data Engineer?

Objetivos

  • Medir el consumo eléctrico de una instalación residencial en diferentes puntos
  • Monitorear el consumo eléctrico mediante AWS IoT
  • Definir una rutina de uso de electrodomésticos para la reducción de costos por energía eléctrica

Medir el consumo eléctrico en instalaciones residenciales 

Hoy en día existen transductores (convertidores de energía) que nos ayudan en la medición de nuestro consumo eléctrico. Para dimensionar el adecuado se deben revisar los parámetros operativos del sensor por ejemplo voltaje, corriente y potencia máxima. 

En el mercado existen diferentes alternativas desde la compra y desarrollo de un sensor, hasta partners de empresas como AWS que tiene todo un catálogo de dispositivos avalados.

En este blog se aborda el uso de un arduino, por los bajos costos pero bien se puede utilizar una raspberry pi, un microcontrolador AVR, ARM, z80, etc.

Cálculo de la tarifa por energía consumida 

De acuerdo al cálculo que se publica anualmente para el ajuste tarifario de la Comisión Federal de Electricidad (CFE) en México, los esquemas de consumo pueden abarcar diferentes cargos como se muestra en la siguiente tabla.

Para ejemplos prácticos en este blog se revisan los cálculos para dos tarifas GDMTH (Gran Demanda en Media Tensión Horaria) y GDMTO (Gran Demanda en Media Tensión Ordinaria).

Desarrollo de dispositivo para el sensor de potencia

Materiales para el desarrollo del dispositivo 

Para la adquisición de datos tanto voltajes, corrientes y potencias se propone el uso del multímetro de la marca Morning group, que nos da la medición con una interfaz USB RS485. 

Esta salida USB es la que se conecta a los pines Rx y Tx del Arduino, cabe mencionar que este dispositivo mide la corriente con un gancho de forma inductiva, es decir, no se debe cortar el cable para realizar la medición de corriente. Algo relevante y por lo cual se eligió este dispositivo es que la data ya la da estandarizada en kWh y de forma cincominutal. 

Esto reduce parte del cálculo para la estimación de tarifas y montos cobrados por CFE.

El dispositivo propuesto para la transmisión de datos es un Arduino MKR WiFi 1010, ya que es de bajo costo, tiene WiFi de serie y es un dispositivo programable microcontrolador AVR.

Tiene entradas análogas, digitales y los pines para el protocolo serial USART y UART que nos permite la conexión USB.

Arduino provee una guía detallada  de cómo conectar este dispositivo a AWS IoT Core de forma segura.

Conexión del Arduino con AWS IoT Core

Introducción

Los dispositivos pueden conectarse a AWS IoT Core mediante los siguientes protocolos: HTTP, WebSockets y MQTT. 

En este blog se ve el caso de uso para la conexión de la placa Arduino MKR WiFi 1010 (o MKR1000) de forma segura a AWS IoT Core mediante el protocolo MQTT. 

Nota: Al conectarse a AWS IoT Core mediante MQTT, los dispositivos deben utilizar certificados X.509 con TLS para la autenticación, ya que AWS IoT Core no admite la autenticación a través de nombre de usuario y contraseña como muchos otros servicios de intermediarios de MQTT. 

Cada placa Arduino MKR con conectividad integrada, incluida la MKR WiFi 1010, está equipada con un elemento criptográfico ATECC508A o ATECC608A de Microchip. Este elemento criptográfico se puede utilizar para generar y almacenar de forma segura una clave ECC (criptografía de curva elíptica) de 256 bits. Las claves ECC de 256 bits tienen una fuerza equivalente a las claves RSA de 3072 bits.

Configuración de Software y Hardware

Si no tiene el IDE de Arduino instalado en su computadora, descárguelo e instálelo.

Una vez que esté instalado, asegúrese de tener el último paquete "Arduino SAMD Boards". Puede comprobarlo abriendo el IDE de Arduino:

  • Menú Herramientas -> Placa: "..." -> Administrador de placa... y buscando "Arduino SAMD". 

A continuación, se instalan las bibliotecas de Arduino con el administrador de bibliotecas del IDE de Arduino. 

Sketch -> Include Library -> Manage Libraries..., se buscan e instalan individualmente cada una de las siguientes bibliotecas:

  • WiFiNINA (o WiFi101 para el MKR1000)
  • ArduinoBearSSL
  • ArduinoECCX08
  • ArduinoMqttCliente
  • Arduino Cloud Provider Examples

Se conecta el MKR WiFi 1010 con el cable micro USB a la computadora. 

Se selecciona el puerto serie en el IDE de Arduino usando el menú 

  • Tools -> Port "..." y también se selecciona Arduino MKR WiFi 1010 en el menú Tools -> Board "...".

Configuración de la tarjeta en AWS IoT Core

Como se mencionó anteriormente, AWS IoT Core requiere que los dispositivos que se conectan mediante el protocolo MQTT utilicen certificados X.509 para la autenticación. 

Usaremos un sketch para generar una solicitud de firma de certificado (CSR) en la placa y luego cargaremos esta CSR en la consola de AWS para crear un certificado X.509.

El CSR se puede generar utilizando un sketch de ejemplo de la biblioteca ArduinoECCX08. 

  • Abra el boceto en el IDE de Arduino usando File -> Examples -> ArduinoECCX08 -> Tools -> ECCX08CSR. 
  • Haga clic en el botón "Upload" para construir y cargar el sketch a la tarjeta.
  • Luego se abre el monitor serial. 
  • Se asegura que la configuración de final de carro esté establecida en "Both NL & CR".

Este sketch le pedirá que configure permanentemente su elemento criptográfico ATECC508A a ECC608A si no está configurado y bloqueado.

Cuando la placa sale de fábrica, el elemento criptográfico se encuentra en un estado no configurado y desbloqueado.

Después de esto, se pide información para ser incluida en el CSR, la mayoría de los campos se pueden dejar en blanco excepto el "Common Name", en la captura de pantalla a continuación se ingresa "MyMKRWiFi1010". 

Para este blog, usaremos el slot 0 para generar y almacenar la clave privada utilizada para firmar la CSR (los slots 1 a 4 se pueden usar para generar y almacenar claves privadas adicionales si es necesario).

Nota: Dado que la clave privada se genera dentro del elemento criptográfico, nunca sale del dispositivo y se almacena de forma segura y no se puede leer.

Se copia el texto de CSR generado que incluye "------BEGIN CERTIFICATE REQUEST-----" y "-----END CERTIFICATE REQUEST-----" y se guarda en un archivo .txt. Este archivo se carga en la consola de AWS de la siguiente forma:

  1. Se inicia sesión en la consola de AWS y se busca el servicio de AWS IoT Core
  2. Una vez dentro del servicio se da clic en Things dentro del menú Managet.
  3. Se da clic en Create things
  4. Se selecciona Create single thing y se da clic en siguiente
  5. Se le da el nombre y se presiona Next, los otros campos pueden estar en blanco.
  6. Se selecciona la opción de Upload CSR y se carga el archivo
  7. En la siguiente pantalla se da clic en Register Thing.
  8. Se  debe observar una pantalla como la siguiente:
  9. Se debe crear una política que permita como action * y como Resource * de esta manera se crea la política para pruebas.
  10. Se asigna la política al certificado.
  11. Se descarga el certificado en la computadora.
  12. Se da clic en Settings para obtener el MQTT endpoint para crear las conexiones en el futuro.
  13. AWS IoT está configurado para su uso con la tarjeta de arduino.

Conexión de la tarjeta como AWS IoT Core

Se abre AWS IoT WiFi Sketck en el IDE de arduino de la siguiente forma: 

  • File-> Arduino-> Cloud Provider Examples -> AWSIoT->AWS_IoT_WiFi

En la biblioteca de arduino_secrets.h se actualiza la configuración WiFi con el SSID y password de la red WiFi a la que se conecta el dispositivo.

// Fill in  your WiFi networks SSID and password
#define SECRET_SSID ""
#define SECRET_PASS ""

Se actualiza el endpoint del broker

// Fill in the hostname of your AWS IoT broker
#define SECRET_BROKER "xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com"

En el sketch se pega el valor del certificado que previamente se descargó

// Fill in the boards public certificate
const char SECRET_CERTIFICATE[] = R"(
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
)";

Se carga el Sketch a la tarjeta y se abre el monitor serial. La tarjeta intenta conectarse a la red WiFi si tiene éxito inmediatamente tratará de conectarse a IoT mediante MQTT.

Interactuando con la tarjeta en AWS IoT Core

Ahora que la tarjeta está conectada exitosamente a AWS IoT, se puede usar la consola de AWS para interactuar con ella. El sketch envía un mensaje de salida cada cinco segundos y escucha los mensajes de entrada.

Realizamos la suscripción del topic dando clic en Suscribe to a topic.

Sketch completo

/*
  AWS IoT WiFi
  This sketch securely connects to an AWS IoT using MQTT over WiFi.
  It uses a private key stored in the ATECC508A and a public
  certificate for SSL/TLS authentication.
  It publishes a message every 5 seconds to arduino/outgoing
  topic and subscribes to messages on the arduino/incoming
  topic.
  The circuit:
  - Arduino MKR WiFi 1010 or MKR1000
  The following tutorial on Arduino Project Hub can be used
  to setup your AWS account and the MKR board:
  https://create.arduino.cc/projecthub/132016/securely-connecting-an-arduino-mkr-wifi-1010-to-aws-iot-core-a9f365


  This example code is in the public domain.
*/

#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include <ArduinoMqttClient.h>
#include <WiFiNINA.h> // change to #include <WiFi101.h> for MKR1000

#include "arduino_secrets.h"

/////// Enter your sensitive data in arduino_secrets.h
const char ssid[]        = SECRET_SSID;
const char pass[]        = SECRET_PASS;
const char broker[]      = SECRET_BROKER;
const char* certificate  = SECRET_CERTIFICATE;

WiFiClient    wifiClient;            // Used for the TCP socket connection
BearSSLClient sslClient(wifiClient); // Used for SSL/TLS connection, integrates with ECC508
MqttClient    mqttClient(sslClient);

unsigned long lastMillis = 0;

void setup() {
  Serial.begin(115200);
  while (!Serial);

  if (!ECCX08.begin()) {
    Serial.println("No ECCX08 present!");
    while (1);
  }

  // Set a callback to get the current time
  // used to validate the servers certificate
  ArduinoBearSSL.onGetTime(getTime);

  // Set the ECCX08 slot to use for the private key
  // and the accompanying public certificate for it
  sslClient.setEccSlot(0, certificate);

  // Optional, set the client id used for MQTT,
  // each device that is connected to the broker
  // must have a unique client id. The MQTTClient will generate
  // a client id for you based on the millis() value if not set
  //
  // mqttClient.setId("clientId");

  // Set the message callback, this function is
  // called when the MQTTClient receives a message
  mqttClient.onMessage(onMessageReceived);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    connectWiFi();
  }

  if (!mqttClient.connected()) {
    // MQTT client is disconnected, connect
    connectMQTT();
  }

  // poll for new MQTT messages and send keep alive
  mqttClient.poll();

  // publish a message roughly every 5 seconds.
  if (millis( ) - lastMillis > 5000) {
    lastMillis = millis();

    publishMessage();
  }
}

unsigned long getTime() {
  // get the current time from the WiFi module 
  return WiFi.getTime();
}

void connectWiFi() {
  Serial.print("Attempting to connect to SSID: ");
  Serial.print(ssid);
  Serial.print(" ");

  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    // failed, retry
    Serial.print(".");
    delay(5000);
  }
  Serial.println();

  Serial.println("You're connected to the network");
  Serial.println();
}

void connectMQTT() {
  Serial.print("Attempting to MQTT broker: ");
  Serial.print(broker);
  Serial.println(" ");

  while (!mqttClient.connect(broker, 8883)) {
    // failed, retry
    Serial.print(".");
    delay(5000);
  }
  Serial.println();

  Serial.println("You're connected to the MQTT broker");
  Serial.println();

  // subscribe to a topic
  mqttClient.subscribe("arduino/incoming");
}

void publishMessage() {
  Serial.println("Publishing message");

  // send message, the Print interface can be used to set the message contents
 

mqttClient.beginMessage("arduino/outgoing");
  mqttClient.print("hello ");
 

mqttClient.print(millis());
  mqttClient.endMessage();
}

void onMessageReceived(int messageSize) {
  // we received a message, print out the topic and contents
  Serial.print("Received a message with topic '");
  Serial.print(mqttClient.messageTopic());
  Serial.print("', length ");
  Serial.print(messageSize);
  Serial.println(" bytes:");

  // use the Stream interface to print the contents
  while (mqttClient.available()) {
    Serial.print((char)mqttClient.read());
  }
  Serial.println();

  Serial.println();
}

Se adapta este código para enviar la medición recibida por el sensor de forma cincominutal y por el protocolo USART al topic.

Creación del Delivery Stream con Amazon Kinesis Firehose

Amazon QuickSight requiere un almacén de datos para crear visualizaciones de los datos del sensor. Este sencillo flujo de entrega de Amazon Kinesis Data Firehose carga continuamente datos en un Bucket de almacenamiento S3

Las siguientes secciones cubren cómo agregar registros a esta transmisión mediante una función Lambda.

  1. En la consola de Kinesis Data Firehose, se crea un nuevo flujo de entrega denominado SensorDataStream.
  2. Deje la fuente predeterminada como Direct PUT or other sources y elija Next.
  3. En la siguiente pantalla, deje todos los valores predeterminados y elija Next.
  4. Seleccione Amazon S3 como destino y cree un Bucket nuevo con un nombre único. Aquí es donde los registros se cargan continuamente para que Amazon QuickSight pueda utilizarlos.
  5. En la siguiente pantalla, se crea un nuevo rol de IAM. Esto otorga permiso al flujo de entrega de Firehose para cargar en S3.
  6. Se selecciona Create Delivery Stream.

Invocando Lambda usando AWS IoT Core rules

Usando AWS IoT Core rules, se reenvían mensajes desde dispositivos a una función Lambda, que puede realizar acciones como cargar en una tabla de Amazon DynamoDB o un depósito S3, o ejecutar datos en varios servicios de Amazon Machine Learning. 

En este caso, la función transforma y agrega un mensaje al flujo de entrega de Kinesis Data Firehose, que luego agrega esos datos a S3.

AWS IoT Core rules usa el MQTT topic stream para desencadenar las interacciones con otros servicios de AWS. Una regla de AWS IoT Core se puede crear mediante una instrucción SQL, un filter topic y o un rule action. 

En este ejemplo Arduino publica mensajes cada cinco minutos sobre el topic arduino/outgoing. Las siguientes instrucciones muestran cómo consumir esos mensajes con una función Lambda.

Creación de la función en lambda

Antes de la creación de la regla en AWS Iot Core, se necesita la función que hace el reenvío de los mensajes.

  1. En la consola de AWS Lambda, se elige Create function
  2. Nombre de la función ArduinoConsumemessage
  3. El runtime es Node.js10.x, para el rol que asumirá se crea uno nuevo con los permisos básicos de ejecución y se da clic en Create.
  4. En IAM se selección el rol ArduinoConsumeMessagge-role-xxx
  5. Se le asigna la política de AmazonkinesisFirehoseFullAccess.
  6. Se pega el siguiente código para realizar el reenvío adicionalmente según el tipo de tarifa de CFE que se quiera calcular se coloca el cálculo en la lambda de esta manera se persiste tanto el dato en crudo de medición como el cobro de CFE.

const AWS = require('aws-sdk')

const firehose = new AWS.Firehose()
const StreamName = "SensorDataStream"

exports.handler = async (event) => {
   
    console.log('Received IoT event:', JSON.stringify(event, null, 2))
   
    let payload = {
        time: new Date(event.time),
        sensor_value: event.sensor_a0
    }
   
    let params = {
            DeliveryStreamName: StreamName,
            Record: {
                Data: JSON.stringify(payload)
            }
        }
       
    return await firehose.putRecord(params).promise()

}

Creación de la regla de AWS IoT Core

Para la creación de la regla se siguieron los siguientes pasos:

  1. En la consola de AWS IoT console, se elige Act
  2. Se da clic en Create
  3. Para la sentencia SQS, hay que copiar y pegar los siguiente:
    SELECT * FROM 'arduino/outgoing’ Esto realiza la suscripción al topic de salida
  4. Se elige Add action, Send a message to a Lambda function, Configure action.
  5. Se selecciona la última función lambda creada
  6. Se crea la regla dando clic en Create rule.

En este escenario cualquier mensaje publicado en el topic arduino/outgoingse reenvía a la función ArduinoConsumeMessage, que transforma y envía el payload a kinesis Data Firehose stream y crea los logs del mensaje con Amazon CloudWatch.

Visualización en QuickSight

Para la visualización con QuickSight se siguen los siguientes pasos:

  1. En la consola de QuickSight se elige Manage Data, New Data Set
  2. Se selecciona S3 como fuente de datos.
  3. Para que SE sea capaz de la extracción de la información a S3 se necesita configurar el manifiesto.
    {
    "fileLocations":[
    {
    "URIPrefixes":[
    "s3://YOUR-BUCKET-NAME/"
    ]
    }
    ],
    "globalUploadSettings":{
    "format":"JSON"
    }
    }
  4. La expresión YOUR-BUCKET-NAME, se cambia por el nombre del bucket con el que se está trabajando y se carga como manifest.json.
  5. Se elige Connect y Visualize, se le dan los permisos necesarios a QuickSight para acceder al bucket.
  6. Finalmente se desarrolla el dashboard final con las visualizaciones y KPIs relevantes para evaluar en qué horas el consumo puede bajar en comparación con las tarifas de CFE.

Conclusión

En este blog se describe el proceso de creación de un sensor para la medición de potencia, el streaming de datos y la transformación en la lambda de S3 para el cálculo tarifario de CFE. Mediante este ejercicio se puede sensar el consumo total de la casa, por electrodoméstico, cuarto, sección u otros.

Al final se pueden crear KPIs que nos indiquen cuál es el consumo total de algún periodo cincominutal, horario, diario, semanal, mensual, bimestral etc. y validar también si los subsidios y cobros están bien hechos.

Este tipo de proyectos personales e individuales pueden ser escalados y aplicados de manera más amplia en proyectos empresariales. El conocimiento y servicios vistos en este tutorial son parte del programa Cloud Data Engineer en AWS.

Deja un comentario

Este sitio está protegido por reCAPTCHA y se aplican la Política de privacidad de Google y los Términos del servicio.