ste proyecto de IoT para control de acceso se centra en el uso de dispositivos RFID con ESP8266 y puertas controladas electrónicamente "Servos", integrados con los servicios de AWS para crear un sistema seguro, escalable y eficiente. Los componentes principales incluyen:
- Dispositivos IoT: Lectoras RFID y controladores de puertas que se comunican con la nube.
- AWS IoT Core: Actúa como broker MQTT para la comunicación entre dispositivos.
- Funciones Lambda: Ejecutan lógica de negocio, como la validación de accesos y actualizaciones de registros.
- DynamoDB: Almacena datos de acceso y registros de dispositivos.
- API Gateway: Facilita la integración con aplicaciones externas para enviar y recibir datos.
Los usuarios presentan sus tarjetas RFID, los dispositivos leen la información y envían los datos a la nube, donde se procesan y verifican mediante funciones Lambda. Dependiendo de la validación, se envían comandos para abrir o cerrar puertas, registrar accesos, y enviar notificaciones. Este sistema proporciona un control de acceso eficiente y seguro, aprovechando la infraestructura de AWS.
Este proyecto está inspirado la siguiente publicación de AWS Aquí.
La siguiente imagen muestra la infraestructura del proyecto, en la que se conecta un ESP8266 a un broker MQTT mediante AWS Iot Core. El ESP8266 se encarga de controlar la puerta y el lector RFID, mientras que la Raspberry Pi actúa como broker MQTT y se comunica con AWS IoT Core.
Para conocer más de la infraestructura implementada mediate Terraform, puede visitar esta documentación.
- Implementar la logica para añadir/actualizar tarjetas RFID.
- Implementar la logica para eliminar tarjetas RFID anteriormente guardadas.
- Implementar la lógica de control de acceso mediante tarjetas RFID.
- Implementar las reglas en AWS IoT Core para invocar las funciones Lambda.
- Implementar base de datos en Dynamo para persistir la información de las tarjetas RFID.
- Implementar infraestructura en AWS paa mejorar mantenibilidad y escalabilidad.
- Implementar la lógica de cambio de estado del lector RFID.
- Implementar apis para la gestión de tarjetas RFID desde un portal web.
- Implementar entidad de usuarios para asocial tarjetas RFID registradas.
- Mejorar procesos de acceso mediante maquinas de estado.
- Guardar información de acceso y eventos en la base de datos.
-
Clonar el repositorio:
git clone https://github.com/potier97/rfid-access-iot.git cd rfid-access-iot
-
Crear y activar el entorno virtual:
python -m venv env # En Windows .\env\Scripts\activate # En macOS y Linux source env/bin/activate
-
Instalar dependencias:
pip install -r requirements.txt
- Introducción
- Requisitos
- Conexión Componentes
- Instalación del Broker Mosquitto
- Ampy - Transferencia de Archivos
- Configuración Inicial del ESP8266
- Definición de Objetos - AWS IoT Core
- Implementar Reglas - AWS IoT Core
- Contribuciones
- Autor
- Licencia
El proyecto RFID Access IoT
permite gestionar el acceso a una puerta utilizando tarjetas RFID. La información de acceso se gestiona a través de un ESP8266 que se comunica con un broker MQTT alojado en una Raspberry Pi y, en futuras versiones, con AWS IoT Core.
Se hace uso de la libreria umqtt.simple
para la comunicación MQTT en el ESP8266, puede encontrar la documentación aquí.
Puede encontrar documentación acercar de MQTT en este enlace de AWS
- Raspberry Pi con Raspbian instalado
- ESP8266 con MicroPython
- Módulo RFID (MFRC522)
- Servomotor
- Tarjetas RFID
- Mosquitto instalado en la Raspberry Pi
- Conexión a Internet
La conexión de los componentes se realiza para dos dispositivos, uno para el control del servo (Puerta) y otro para el lector RFID. La conexión se realiza de la siguiente manera:
Tenga en cuenta los pines I/O de la ESP8266
ESP8266 | Servo |
---|---|
D5 (GPIO14) | Signal |
NN | VCC |
GND | GND |
El servo se alimenta con 5V de una fuente independiente y se comparte la tierra (GND) con el ESP8266.
Se conecta un led en el pin D0 (GPIO16) para indicar el estado del dispositivo.
ESP8266 | Lector RFID |
---|---|
D5 (GPIO14) | SCK |
D7 (GPIO13) | MOSI |
D6 (GPIO12) | MISO |
D2 (GPIO4) | RST |
D2 (GPIO5) | SDA |
GND | GND |
3V3 | 3.3V |
El lector RFID se alimenta con 3.3V y se comparte la tierra (GND) con el ESP8266.
Se conecta un led en el pin D0 (GPIO16) para indicar el estado del dispositivo.
-
Instalar Mosquitto:
sudo apt update sudo apt upgrade -y sudo apt install -y mosquitto mosquitto-clients
-
Iniciar el servicio de Mosquitto:
sudo systemctl enable mosquitto
Importante: Es necesario modificar el archivo ubicado en
/etc/mosquitto/mosquitto.conf
para habilitar la autenticación de usuarios y la comunicación por el puerto 1883. Para ello, edite el documento usandonano
sudo nano /etc/mosquitto/mosquitto.conf Agruegue las siguientes líneas al final del archivo: - listener 1883 - allow_anonymous true
Su archivo debería verse de la siguiente manera:
Iniciar o reinice el servicio el servicio:
start
orestart
sudo systemctl start mosquitto
-
Comprobar que el servicio está en ejecución:
sudo systemctl status mosquitto
-
Hacer pruebas de conexión con el broker: En una terminal, suscribirse a un tópico:
mosquitto_sub -h localhost -t test
En otra terminal, publicar un mensaje en el tópico:
mosquitto_pub -h localhost -t test -m "Hello, world!"
Deberías ver el mensaje en la terminal donde te suscribiste al tópico.
Para transferir archivos al ESP8266, utilizaremos ampy
. Para instalarlo, ejecuta el siguiente comando:
pip install adafruit-ampy
- Para verificar que
ampy
se instaló correctamente, ejecuta el siguiente comando:
ampy --help
- Trasferir archivos al ESP8266:
ampy --port com6 put main.py
- Obtener la lista de archivos en el ESP8266:
ampy --port com6 ls
- Obtener un archivo del ESP8266:
ampy --port com6 get main.py
- Eliminar un archivo del ESP8266:
ampy --port com6 rm main.py
El desarrollo d este proyecto se realiza de acuerdo a este otro proyecto: ESP8266-MicroPython.
Este ejemplo consiste en la publicación de mensajes desde una ESP8266 que se conecta a un broker MQTT en una Raspberry Pi. Este captura los posible mensjaes a los que está suscrito y actúa en consecuencia.
Principalmente, el ESP8266 se conecta a la red WiFi y al broker MQTT. Luego, se suscribe a un tópico y publica mensajes en otro tópico.
Los mensajes a los que está suscrito son unicamente para abrir o cerrar la puerta
y bloquear o desbloquear la puerta
, que consiste en mover un servo a distintos grados.
El código del ESP8266 se encuentra en el archivo door.py
y se puede transferir al ESP8266 utilizando ampy
. Este consiste en una clase llamada Door
y es explicada a continución:
- thing/door/open: Abre la puerta (mueve el servo a 180°).
- thing/door/close: Cierra la puerta (mueve el servo a 0°).
- thing/door/lock: Bloquea la puerta (desactiva el servo y apaga el LED).
- thing/door/unlock: Desbloquea la puerta (activa el servo y enciende el LED).
Una vez que el ESP8266 esté conectado al broker MQTT, enviará y recibirá mensajes para controlar la puerta. Asegúrate de que tu broker MQTT esté funcionando correctamente y que los temas MQTT estén configurados según tu necesidad.
Ejemplo de Publicación de Mensajes Puedes usar cualquier cliente MQTT para enviar mensajes a los temas correspondientes. Aquí hay un ejemplo usando mosquitto_pub:
# Abrir la puerta
mosquitto_pub -h <broker_ip> -t thing/door/open -m ""
# Cerrar la puerta
mosquitto_pub -h <broker_ip> -t thing/door/close -m ""
# Bloquear la puerta
mosquitto_pub -h <broker_ip> -t thing/door/lock -m ""
# Desbloquear la puerta
mosquitto_pub -h <broker_ip> -t thing/door/unlock -m ""
Por el momento el mensaje a enviar es vacío, se espera que este se pueda enviar la información de la tarjeta RFID.
La clase Door controla la lógica del sistema de acceso. Aquí tienes una explicación de sus componentes principales:
- Constructor (init): Inicializa los atributos del objeto Door, conecta al servidor MQTT y configura las suscripciones a los temas.
def __init__(self, mqtt_server, client_id, thing_name, servo_pin=14, led_pin=16):
- Callback de Suscripción (sub_cb): Maneja los mensajes recibidos y llama a las funciones correspondientes según el tema del mensaje.
def sub_cb(self, topic, msg):
- Funciones de Manejo: Controlan las acciones de abrir, cerrar, bloquear y desbloquear la puerta.
def handle_open(self):
def handle_close(self):
def handle_lock(self):
def handle_unlock(self):
- Reconexión (restart_and_reconnect): Reinicia el ESP8266 y reconecta al broker MQTT en caso de error.
def restart_and_reconnect(self):
- Conexión y Suscripción (connect_and_subscribe): Conecta al servidor MQTT y se suscribe a los temas necesarios.
def connect_and_subscribe(self):
- Escucha de Mensajes (listen): Mantiene el ESP8266 escuchando mensajes MQTT y maneja las excepciones.
def listen(self):
La clase main.py
inicializa el sistema y ejecuta la lógica principal.
- Ejecución Principal: Crea una instancia de la clase Door y llama a la función listen para comenzar a escuchar los mensajes MQTT.
if __name__ == '__main__':
client_id = ubinascii.hexlify(unique_id())
mqtt_server = '192.168.1.24'
thing_name = 'thing'
door_controller = Door(mqtt_server, client_id, thing_name)
door_controller.listen()
Este sección muestra cómo utilizar un lector RFID para leer tarjetas y enviar la información al servidor MQTT. El sistema está diseñado para detectar tarjetas RFID y publicar el UID de la tarjeta en un tema MQTT. (Ejemplo Simple), este lo puede encontrar en el archivo scripts/main_read_rfid.py
.
El uso de RFID se basa en el proyecto de Micropython RFID
El código inicializa el LED y configura los pines para el lector RFID.
from machine import Pin, SoftSPI, unique_id
from time import sleep
from ubinascii import hexlify
from umqtt.simple import MQTTClient
import mfrc522
import ujson
# Inicializa el LED
led = Pin(16, Pin.OUT)
# Configuración del lector RFID
sck = Pin(14, Pin.OUT)
mosi = Pin(13, Pin.OUT)
miso = Pin(12, Pin.IN)
# Configuración del pin de interrupción
print("Escanea una tarjeta RFID...")
Se configura el cliente MQTT para conectarse al servidor y definir el tema donde se publicarán los mensajes.
# Configuración del cliente MQTT
mqtt_server = 'BROKER_IP'
client_id = hexlify(unique_id())
topic_pub = 'thing/rfid/open'
client = MQTTClient(client_id, mqtt_server)
client.connect()
Se configura el lector RFID y se define la función read_rfid para leer las tarjetas y obtener el UID.
Cuando se detecta una tarjeta, el código convierte el UID a formato hexadecimal y crea un mensaje JSON. Este mensaje se publica en el tema thing/rfid/open.
spi = SoftSPI(baudrate=100000, polarity=0, phase=0, sck=sck, mosi=mosi, miso=miso)
spi.init()
rdr = mfrc522.MFRC522(spi, gpioRst=4, gpioCs=5)
# Función para leer la tarjeta y obtener el UID
def read_rfid():
while True:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, uid) = rdr.anticoll()
if stat == rdr.OK:
print("Tarjeta detectada!")
uid_hex = ''.join(['{:02X}'.format(x) for x in uid])
# Crear el mensaje JSON
message = ujson.dumps({
"type": "0x%02x" % tag_type,
"uid": uid_hex
})
# Publicar el mensaje en el tema MQTT
client.publish("thing/rfid/open", message)
print("Mensaje publicado:", message)
# Enciende el LED para indicar que se ha leído la tarjeta
led.value(1)
sleep(1)
led.value(0)
# Ejecutar la lectura
read_rfid()
Ejemplo de implementación de la lectura de tarjetas RFID.
Este apartado consiste en la configuración de las esp8266 para extender la lógica anterior en los controles primarios de acceso mediante los siguientes publicaciones sobre el broker MQTT, cabe agregar que la comunicación de este dispositivo se realiza en doble vía, es decir, este nodo se suscribe a unos topics para actualizar el estado del lector, y publica en otros para enviar la información de las tarjetas RFID que se detectan.
- thing/rfid/open: Envia el UID y tipo de la tarjeta RFID para soliciar el acceso.
- thing/rfid/update: Envia los datos de las tarjetas RFID para asociar a un usuario nuevo o actualizar la información de un usuario existente.
- thing/rfid/remove: Envio de la información de la tarjeta RFID para eliminarla de la lista de permitidos y desasoaciarla de un usuario.
- thing/rfid/status: Actualiza el estado del lector RFID
locked
-ready
-remove
-update
.
En este ejemplo se agrega una tarjeta RFID a la lista de permitidos, para ello se envía la información de la tarjeta al broker MQTT. Es recibido por la suscripción thing/rfid/update
Para ejemplos practicos se agrega el UID de la tarjeta en memoria del dispositivo RFID.
De acuerdo al ejemplo anterior, al tener un UID de una tarjeta guarda en memoria, se cambia el estado a ready
para que el lector RFID envie el UID de la tarjeta y su tipo a la suscripción thing/rfid/open
para solicitar el acceso.
Hay que tener por lo menos una tarjeta en memoria para que el sistema funcione, posteriormente el listado de aceptados persistirá en una base de datos en la Nube de AWS.
El estado del lector se debe cambiar a remove
para remover accesos de la lista de permitidos.
En este ejemplo se elimina una tarjeta RFID de la lista de permitidos, para ello se envía la información de la tarjeta en la publicación thing/rfid/remove
Cuando se cambia al estado locked
el lector RFID no ejecuta ninguna acción, esto se puede utilizar para bloquear el acceso a la puerta.
Para definir los objetos en AWS IoT Core, se debe crear un Thing
y un Policy
para el dispositivo. Para ello, se debe seguir los siguientes pasos:
En este ejemplo se conecta una Raspberry Pi a AWS IoT Core y se ejecuta un script en Python para publicar mensajes en distintos tópics de MQTT y nos conectamos al cliente MQTT de AWS para ejecutar pruebas.
También puede ver este tutorial para crear un dispositivo en AWS IoT Core.
- Ingresar a la consola de AWS y buscar el servicio
IoT Core
. - En el menú lateral, seleccionar
All things
y hacer clic enObject
. - Hacer clic en
Create
y seleccionarCreate thing
. - Ingresar el nombre del dispositivo, se selecciona en
Unnamed shadow (classic)
para asociar una sombra al dispositivo y hacer clic enNext
.
En este ejemplo el dispositivo se llama
rpi_obj_test
.
- Seleccionar
Auto-generate a new certificate (recommended)
y hacer clic enNext
.
- Se asocian las politicas al dispositivo, en este caso se selecciona
test_rpi
y luego se hace clic enCreate thing
.
Más adelante se definirá y explicará la política
test_rpi
para el dispositivo.
- Se mostrará un modal para descargar los certificados y la clave privada del dispositivo. Descargar los archivos y hacer clic en
Done
.
Los archivos que serán utilizados son los terminados en: -
....certificate.pem.crt
-....private.pem.key
-....AmazonRootCA1.pem
Listo el dispositivo ha sido creado en AWS IoT Core y este podrá ser visualizado en la consola de AWS, en la sección Things
.
Para crear una política, se debe seguir los siguientes pasos:
- En el menú lateral, seleccionar
Secure
y hacer clic enPolicies
. - Hacer clic en
Create
y seleccionarCreate a policy
. - Ingresar el nombre de la política, se selecciona
Advanced mode
y se ingresa la siguiente política:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:*",
"Resource": "*"
}
]
}
La politica creada test_rpi
y que se asocia al dispositivo rpi_obj_test
tiene la siguiente definición:
Esta política permite al dispositivo realizar cualquier acción en AWS IoT Core, la puede ver aqui y está definida así:
Cambie
<REGION>
por la región de su cuenta de AWS y<ACOUNT_ID>
por el ID de su cuenta.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:client/MyRaspberryPi"
},
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/$aws/things/MyRaspberryPi/shadow/update"
},
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/$aws/things/MyRaspberryPi/shadow/update/delta"
},
{
"Effect": "Allow",
"Action": "iot:Receive",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/$aws/things/MyRaspberryPi/shadow/update/delta"
},
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": [
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/open",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/update",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/remove",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/one",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/two",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/three"
]
},
{
"Effect": "Allow",
"Action": "iot:Receive",
"Resource": [
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/open",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/update",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/remove",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/one",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/two",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/three"
]
},
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": [
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/open",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/update",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/remove",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/one",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/two",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/three"
]
}
]
}
La politica funciona de la siguiente manera:
- Permite al dispositivo suscribirse al tópico
$aws/things/MyRaspberryPi/shadow/update/delta
. - Permite al dispositivo publicar mensajes en los tópicos
thing/rfid/open
,thing/rfid/update
,thing/rfid/remove
,thing/rfid/one
,thing/rfid/two
ything/rfid/three
. - Permite al dispositivo recibir mensajes en los tópicos
thing/rfid/open
,thing/rfid/update
,thing/rfid/remove
,thing/rfid/one
,thing/rfid/two
ything/rfid/three
. - Permite al dispositivo suscribirse a los tópicos
thing/rfid/open
,thing/rfid/update
,thing/rfid/remove
,thing/rfid/one
,thing/rfid/two
ything/rfid/three
.
Permite que el dispositivo MyRaspberryPi se conecte al broker de AWS IoT. Sin este permiso, el dispositivo no podrá establecer una conexión con el servicio de IoT.
iot:Connect
: Politica para conectar dispositivos al broker MQTT de AWS IoT.Resource
: ARN del cliente MQTT de AWS IoT, este debe tener la estructuraarn:aws:iot:<REGION>:<ACOUNT_ID>:client/<CLIENT_ID>
, en el que client_id es el ID del dispositivo definido en la conexión del dispositivo, Ejemplo.
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:client/MyRaspberryPi"
}
Permite que el dispositivo MyRaspberryPi publique mensajes en el tema específico para actualizar su estado (shadow). Este tema se utiliza para mantener el estado reportado del dispositivo.
iot:Publish
: Politica para publicar mensajes en un tópico específico.
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/$aws/things/MyRaspberryPi/shadow/update"
}
Permite que el dispositivo MyRaspberryPi se suscriba a las actualizaciones del shadow, específicamente al tema update/delta. Esto es esencial para recibir notificaciones cuando hay cambios en el shadow del dispositivo.
iot:Subscribe
: Politica para suscribirse a un tópico específico.
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/$aws/things/MyRaspberryPi/shadow/update/delta"
}
Permite que el dispositivo MyRaspberryPi reciba mensajes del tema update/delta. Es complementario al permiso de suscripción y asegura que el dispositivo puede procesar los mensajes que llegan a ese tema.
iot:Receive
: Politica para recibir mensajes de un tópico específico.
{
"Effect": "Allow",
"Action": "iot:Receive",
"Resource": "arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/$aws/things/MyRaspberryPi/shadow/update/delta"
}
Permite que el dispositivo publique mensajes en varios temas relacionados con RFID. Cada tema puede corresponder a diferentes eventos o datos asociados con el uso de RFID en el dispositivo.
iot:Publish
: Politica para publicar mensajes en varios tópicos.
{
"Effect": "Allow",
"Action": "iot:Publish",
"Resource": [
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/open",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/update",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/remove",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/one",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/two",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/three"
]
}
Permite que el dispositivo reciba mensajes de varios temas relacionados con RFID. Esto asegura que el dispositivo puede escuchar y procesar información proveniente de diferentes eventos RFID.
iot:Receive
: Politica para recibir mensajes de varios tópicos.
{
"Effect": "Allow",
"Action": "iot:Receive",
"Resource": [
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/open",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/update",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/remove",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/one",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/two",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topic/thing/rfid/three"
]
}
Permite que el dispositivo se suscriba a varios temas relacionados con RFID. La suscripción a estos temas asegura que el dispositivo puede recibir mensajes cuando ocurren eventos específicos relacionados con RFID.
iot:Subscribe
: Politica para suscribirse a varios tópicos.
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": [
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/open",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/update",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/remove",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/one",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/two",
"arn:aws:iot:<REGION>:<ACOUNT_ID>:topicfilter/thing/rfid/three"
]
}
Para publicar mensajes en AWS IoT Core, se hace uso del Script.
La estructura del ejemplo se organiza de la siguiente manera:
Se configura un entorno virtual y se instalan las dependencias necesarias, en este caso paho-mqtt
.
y se descargan y se copian los certificados y la clave privada del dispositivo en la misma carpeta del script mqtt_connect.py
.
El script se suscribe a los tópicos:
thing/rfid/one
thing/rfid/two
thing/rfid/three
$aws/things/MyRaspberryPi/shadow/update
El código se estructura de la siguiente manera:
- Configuración de Certificados y Conexión
Define las rutas a los certificados y el endpoint del broker de AWS IoT.
ca_path = "AmazonRootCA1.pem"
cert_path = "certificate.pem.crt"
key_path = "private.pem.key"
mqtt_endpoint = "<endpoint>.iot.<region>.amazonaws.com"
client_id = "MyRaspberryPi"
- Temas para Publicación y Suscripción
Especifica los temas para actualizar y recibir actualizaciones del shadow, así como otros temas para suscripción.
shadow_update_topic = "$aws/things/MyRaspberryPi/shadow/update"
shadow_delta_topic = "$aws/things/MyRaspberryPi/shadow/update/delta"
topics_to_subscribe = [
"thing/rfid/one",
"thing/rfid/two",
"thing/rfid/three"
]
- Callbacks de Conexión y Mensajes
Configura funciones callback para manejar la conexión y la recepción de mensajes.
def on_connect(client, userdata, flags, rc, properties=None):
print(f"Conectado con el código {rc}")
client.subscribe(shadow_delta_topic, qos=0)
for topic in topics_to_subscribe:
client.subscribe(topic, qos=0)
def on_message(client, userdata, message):
print(f"Mensaje recibido en el tema {message.topic}: {message.payload.decode()}")
- Configuración del Cliente MQTT y Conexión
Configura el cliente MQTT con TLS/SSL y lo conecta al endpoint de AWS IoT.
client = mqtt.Client(client_id=client_id, protocol=mqtt.MQTTv5)
client.tls_set(ca_certs=ca_path, certfile=cert_path, keyfile=key_path, cert_reqs=ssl.CERT_REQUIRED, tls_version=2, ciphers=None)
client.on_connect = on_connect
client.on_message = on_message
client.connect(mqtt_endpoint, port=8883)
client.loop_start()
- Bucle Principal para Publicar Mensajes
Publica mensajes en los temas definidos y actualiza el estado del shadow cada 5 segundos.
try:
while True:
for topic in topics_to_subscribe:
message = {
"timestamp": time.time(),
"data": f"Este es un mensaje de prueba del topic: {topic}"
}
publish_message(topic, message)
state = {
"device": {
"status": "active",
"uptime": time.time()
}
}
update_shadow_state(state)
time.sleep(5)
except KeyboardInterrupt:
client.loop_stop()
client.disconnect()
Ejecución del Script en la Raspberry Pi.
Se ejecuta el script y se observa la conexión al broker de AWS IoT Core y la suscripción a los tópicos definidos.
Se publican mensajes relacionados a los tópicos thing/rfid/one
, thing/rfid/two
y thing/rfid/three
y se escuchan al mismo tiempo.
Mientras que en la consola se suscribe al tópico thing/rfid/one
para visualizar los mensajes publicados.
Ahora se publica un mensaje desde la consola de AWS IoT Core en el tópico thing/rfid/one
y se visualiza en la terminal de la Raspberry Pi.
Y se ve el mensaje publicado desde el script de la RPI
En AWS IoT Core, las reglas permiten procesar mensajes MQTT y tomar acciones en función de los datos recibidos. En este caso vamos a hacer un ejemplo de definición de una regla para invocar una función Lambda.
Creamos una función lambda desde la consola de AWS llamada test_invoked_from_iot_core
y escogemos las opciones que se muestran en la imagen
El contenido de la función lambda es el siguiente:
export const handler = async (event, context) => {
const { uid, type } = event;
if (!uid || !type ) {
console.log("Invalid input, id and tipo are required");
return {
statusCode: 400,
body: JSON.stringify({ message: "Invalid input, id and tipo are required" }),
};
}
console.log(uid);
console.log(type);
const response = {
statusCode: 200,
body: JSON.stringify('Success'),
};
return response;
}
Este ejemplo unicamente muestra en la consola el UID y el tipo de la tarjeta RFID que se recibe en el mensaje. Esto se visualizará por medio de CloudWatch.
Definimos el código de la lambda para recibir el mensaje proveniente del topic +/rfid/open
y dentro de esta publicación vamos a recibir en el contenido del mensaje el UID de la tarjeta RFID y el tipo de tarjeta. y tendrá la estructura de la siguiente manera:
{
"uid": "0x1234567890",
"type": "0x01"
}
El comodin
+
se utiliza para recibir mensajes de cualquier tópico que termine en/rfid/open
. Esto nos ayuda a que el sistema sea manenible a medida que se agregan más dispositivos. Recuerde que la primera parte del tópico es el nombre del dispositivo, y este deberia ser único para cada dispositivo.
Desde el cliente MQTT de AWS IoT Core se publica un mensaje en el tópico thing/rfid/open
enviando el mensaje con el UID y el tipo de la tarjeta RFID.
Para crear una regla desde la consola de AWS IoT Core, se selecciona en Rules
desde el menu de Message Routing, y se hace clic en Create
. Se define el nombre de la regla y la descripción.
En la definición de la sentencia SQL se seleccion la versión SQL 2016-03-23
y se define la sentencia SQL para filtrar los mensajes que se reciben en el tópico `+/rfid/open y que tengan el contenido del mensaje con el UID y el tipo de la tarjeta RFID.
SELECT * FROM '+/rfid/open' WHERE uid <> NULL AND type <> NULL
Si quiere más información sobre la sentencia SQL puede ver la documentación aquí
Luego se selecciona las acciones que va a realizar al invocar esta regla
Aqui se define:
- El servicio que se va a llamar, este caso una función lambda
- La función lambda que se va a invocar que corresponde a
test_invoked_from_iot_core
. - La versión de la función lambda, por defecto se selecciona la última versión.
Documentación de como generar una acción con una función lambda aquí
También se pueden definir más de una acción al ejecturar la regla
Asi mismo se puede definir una acción de error, en el caso de que la regla falle.
Por último se muestra un resumen de la regla, en esta se valida que todas las opciones sea correcta, luego de esto se hace clic en Create
.
Se publica un mensaje en el tópico thing/rfid/open
con el contenido del mensaje con el UID y el tipo de la tarjeta RFID.
En los registros de CloudWatch se visualiza el mensaje que se recibe en la función lambda.
Se puede ver que el mensaje se recibe correctamente y se visualiza en la consola de CloudWatch.
Ahora se publica un mensaje en el tópico thing/rfid/open
con el contenido de UID y type vacio.
Se visualiza en los registros de CloudWatch que el mensaje se imprime un mensaje de error.
Si no se envía el mensaje con el UID y el tipo de la tarjeta RFID, la función lambda no se ejecutará.
Para conectar el ESP8266 a AWS IoT Core, se puede orientar en el siguiente tutorial para conectar un ESP8266 a AWS IoT Core.
Es importante mencionar que la versión del firmware
del ESP8266 corresponde al v1.19.1
y lo puede encontrar en el siguiente link ESP8266 Firmware.
Para las conexión a AWS IoT Core se debe tener en cuenta que es necesario tener el certificado y la clave privada del dispositivo, recuerde que estos se generan al momento de crear o definir el dispositivo.
certificate.pem.crt
private.pem.key
Estos los puede pasar a la memoria del ESP8266 utilizando ampy
ampy --port com6 put <ORIGEN-ARCHIVO> certificate.pem.crt
ampy --port com6 put <ORIGEN-ARCHIVO> private.pem.key
No hay mecesidad de convertirlos, ya que estos son leidos y son codificados en base64. esto por medio del método
read_cert
de la clasedoor.py
. Este lo puede encontrar en el archivo door.py.
Puede guiarse de este tutorial para realizar la conexión del ESP8266 a AWS IoT Core, así mismo este ofrece una definición de las reglas para la invocación de funciones lambda de acuerdo a comportamientos esperados.
- Hacer un fork del repositorio.
- Crear una nueva rama (
git checkout -b feature-nueva-funcionalidad
). - Hacer commit de los cambios (
git commit -am 'Agregar nueva funcionalidad'
). - Hacer push a la rama (
git push origin feature-nueva-funcionalidad
). - Crear un Pull Request.
Este proyecto está bajo la Licencia MIT.