Este artículo tiene como propósito mostrar los aspecto principales identificados durante la presentación de mi proyecto de grado.
Contexto
Básicamente mi proyecto es un diseño de un sistema de información del control de acceso para la biblioteca de mi universidad. Para no extender demasiado este artículo, se presentará un resumen sencillo del funcionamiento del sistema.
Problemática
Actualmente, el acceso a los servicio y salón utilizado por los estudiantes en la biblioteca se gestiona de forma manual, por tal motivo se ha planteado el diseño de un sistema de gestión de información para el control de acceso a dichos servicios.
El objetivo principal es integrar un sistema que utilice el carnet del usuario de la biblioteca escaneado a través de un lector de código QR al momento de ingresar a la biblioteca. Este sistema permitiría registrar de manera automatizada y precisa tanto el ingreso como la salida del estudiante de la biblioteca, además de identificar el área específica a la que se dirige.
Con esta propuesta se busca mejorar la eficiencia en el control de acceso y en el registro del uso de los servicios, proporcionando una solución tecnológica que optimice la gestión de la biblioteca.
Requerimientos
Establecer un mecanismo de identificación y correcta autenticación de los usuarios para mantener trazabilidad de los usuarios de los servicios de la biblioteca, por medio de carnet de acceso.
El sistema se encarga de contabilizar la cantidad de usuarios que acceden a la biblioteca.
Reportar la cantidad de usuarios que acceden a la biblioteca, también reportar los salones y servicios que utilizan los estudiantes.
El sistema valida la entrada de los usuarios mediante el escaneo del códigos QR que se encuentra en el carnet de los usuarios.
El sistema se conectará como cliente hacia un servidor web (Azure) en el que estará alojada en una base de datos MySQL.
Vista general
Para implementar el proyecto se determinó que usando un Raspberry Pi (RPi) como dispositivo principal para gestionar el acceso a los salones.
¿Como funciona?
La RPi tiene tres funciones fundamentales para permitir o denegar el acceso:
El RPi estará conectado a un escáner QR y a una cerradura electrónica magnética.
El RPi tiene el rol de hacer consultas a un servidor de base de datos; si el usuario es válido, el RPi enviará un pulso eléctrico a la cerradura para permitir el acceso.
Además, el RPi registra en un servidor de base de datos los accesos realizados por los usuarios.
Diagrama de bloques:
Diagrama de secuencia:
Base de Datos
Diagrama Entidad Relación
Diccionario de datos
Tabla: UsuariosInternos
Campo | Tipo de Dato |
---|---|
Id | INT |
Tipo | ENUM ('Estudiante', 'Docente', 'Administrativo') |
Nombre | VARCHAR(100) |
Id_carrera | INT |
Fecha_de_ingreso | DATETIME |
Fecha_de_salida | DATETIME |
Estado | BIT |
Tabla: UsuariosExternos
Campo | Tipo de Dato |
---|---|
Id | INT |
Identificacion | VARCHAR(50) |
Nombre | VARCHAR(100) |
Nacionalidad | ENUM ('Dominicano', 'Extranjero') |
Universidad | VARCHAR(100) |
Organizacion | VARCHAR(100) |
Fecha_de_ingreso | DATETIME |
Fecha_de_salida | DATETIME |
Estado | BIT |
Tabla: CodigosQRInterno
Campo | Tipo de Dato |
---|---|
Id | INT |
Id_usuario | INT |
Codigo | VARCHAR(50) |
Fecha_creacion | DATETIME |
Fecha_expiracion | DATETIME |
Estado | BIT |
Tabla: CodigosQRExternos
Campo | Tipo de Dato |
---|---|
Id | INT |
Id_usuario | INT |
Codigo | VARCHAR(50) |
Fecha_creacion | DATETIME |
Fecha_expiracion | DATETIME |
Estado | BIT |
Tabla: Salones
Campo | Tipo de Dato |
---|---|
Id | INT |
Nombre | VARCHAR(100) |
Fecha_asignacion | DATETIME |
Fecha_desasignacion | DATETIME |
Estado | BIT |
Tabla: RaspberryPi
Campo | Tipo de Dato |
---|---|
Id | INT |
Nombre | VARCHAR(100) |
Version | VARCHAR(50) |
Fecha_asignacion | DATETIME |
Fecha_desasignacion | DATETIME |
Estado | BIT |
Tabla: Salon_Raspberry
Campo | Tipo de Dato |
---|---|
Id | INT |
Id_salon | INT |
Id_raspberry | INT |
Fecha_asignacion | DATETIME |
Fecha_desasignacion | DATETIME |
Estado | BIT |
Tabla: Transacciones
Campo | Tipo de Dato |
---|---|
Id | BIGINT |
Id_usuario | INT |
QR_Interno | INT |
QR_Externo | INT |
Id_salon | INT |
Fecha_entrada | DATETIME |
Fecha_salida | DATETIME |
Estado | BIT |
Tabla: Credenciales
Campo | Tipo de Dato |
---|---|
Id | INT |
Nombre | VARCHAR(50) |
VARCHAR(50) | |
Password | VARCHAR(255) |
Tipo | ENUM ('Administrador', 'Moderador') |
Estado | BIT |
Tabla: UsuariosBloqueados
Campo | Tipo de Dato |
---|---|
Id | INT |
Id_usuario | INT |
Fecha_bloqueo | DATETIME |
Motivo | VARCHAR(255) |
Estado | BIT |
Tabla: Carreras
Campo | Tipo de Dato |
---|---|
Id | INT |
Nombre | VARCHAR(50) |
Fecha_creacion | DATETIME |
Estado | BIT |
Script base de datos
CREATE TABLE `UsuariosInternos` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Tipo` ENUM ('Estudiante', 'Docente', 'Administrativo') NOT NULL,
`Nombre` VARCHAR(100) NOT NULL,
`Id_carrera` INT,
`Fecha_de_ingreso` DATETIME NOT NULL,
`Fecha_de_salida` DATETIME,
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `UsuariosExternos` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Identificacion` VARCHAR(50) NOT NULL,
`Nombre` VARCHAR(100) NOT NULL,
`Nacionalidad` ENUM ('Dominicano', 'Extranjero') NOT NULL,
`Universidad` VARCHAR(100),
`Organizacion` VARCHAR(100),
`Fecha_de_ingreso` DATETIME NOT NULL,
`Fecha_de_salida` DATETIME,
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `CodigosQRInterno` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Id_usuario` INT NOT NULL,
`Codigo` VARCHAR(50) UNIQUE NOT NULL,
`Fecha_creacion` DATETIME,
`Fecha_expiracion` DATETIME,
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `CodigosQRExternos` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Id_usuario` INT NOT NULL,
`Codigo` VARCHAR(50) UNIQUE NOT NULL,
`Fecha_creacion` DATETIME,
`Fecha_expiracion` DATETIME,
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `Salones` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Nombre` VARCHAR(100) NOT NULL,
`Fecha_asignacion` DATETIME NOT NULL,
`Fecha_desasignacion` DATETIME,
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `RaspberryPi` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Nombre` VARCHAR(100) NOT NULL,
`Version` VARCHAR(50) NOT NULL,
`Fecha_asignacion` DATETIME NOT NULL,
`Fecha_desasignacion` DATETIME,
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `Salon_Raspberry` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Id_salon` INT NOT NULL,
`Id_raspberry` INT NOT NULL,
`Fecha_asignacion` DATETIME,
`Fecha_desasignacion` DATETIME,
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `Transacciones` (
`Id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`Id_usuario` INT NOT NULL,
`QR_Interno` INT,
`QR_Externo` INT,
`Id_salon` INT NOT NULL,
`Fecha_entrada` DATETIME,
`Fecha_salida` DATETIME,
`Estado` BIT NOT NULL DEFAULT 0,
constraint restriccion_qr_usuarios check
(
(QR_Interno is not null and QR_Externo is null) or
(QR_Interno is null and QR_Externo is not null)
)
);
CREATE TABLE `Credenciales` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Nombre` VARCHAR(50) NOT NULL,
`Email` VARCHAR(50) NOT NULL,
`Password` VARCHAR(255) NOT NULL,
`Tipo` ENUM ('Administrador', 'Moderador'),
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `UsuariosBloqueados` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Id_usuario` INT NOT NULL,
`Fecha_bloqueo` DATETIME,
`Motivo` VARCHAR(255),
`Estado` BIT NOT NULL DEFAULT 1
);
CREATE TABLE `Carreras` (
`Id` INT PRIMARY KEY AUTO_INCREMENT,
`Nombre` VARCHAR(50) NOT NULL,
`Fecha_creacion` DATETIME NOT NULL,
`Estado` BIT NOT NULL DEFAULT 1
);
ALTER TABLE `CodigosQRInterno` ADD FOREIGN KEY (`Id_usuario`) REFERENCES `UsuariosInternos` (`Id`);
ALTER TABLE `Transacciones` ADD FOREIGN KEY (`Id_salon`) REFERENCES `Salon_Raspberry` (`Id`);
ALTER TABLE `Salon_Raspberry` ADD FOREIGN KEY (`Id_salon`) REFERENCES `Salones` (`Id`);
ALTER TABLE `Salon_Raspberry` ADD FOREIGN KEY (`Id_raspberry`) REFERENCES `RaspberryPi` (`Id`);
ALTER TABLE `UsuariosBloqueados` ADD FOREIGN KEY (`Id_usuario`) REFERENCES `UsuariosInternos` (`Id`);
ALTER TABLE `UsuariosInternos` ADD FOREIGN KEY (`Id_carrera`) REFERENCES `Carreras` (`Id`);
ALTER TABLE `Transacciones` ADD FOREIGN KEY (`QR_Interno`) REFERENCES `CodigosQRInterno` (`Id`);
ALTER TABLE `Transacciones` ADD FOREIGN KEY (`QR_Externo`) REFERENCES `CodigosQRExternos` (`Id`);
ALTER TABLE `CodigosQRExternos` ADD FOREIGN KEY (`Id_usuario`) REFERENCES `UsuariosExternos` (`Id`);
Script para crear las restricciones de
Tabla UsuariosInternos
-- RESTRICCIONES
-- Delimiter
-- UsuariosInternos
DELIMITER $$
CREATE TRIGGER trigger_estudiante
BEFORE INSERT ON UsuariosInternos
FOR EACH ROW
BEGIN
IF NEW.Tipo != 'Estudiante' AND NEW.Id_carrera IS NOT NULL THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'No se pueden insertar valores en el campo Id_carrera para usuarios que no sean estudiantes';
END IF;
END $$
DELIMITER ;
Script para crear las restricciones de
Tabla Transacciones
-- Transacciones
DELIMITER $$
CREATE TRIGGER trigger_inserQr
BEFORE INSERT ON Transacciones FOR EACH ROW
BEGIN
if (new.QR_Interno is not null and new.QR_Externo is not null) then
signal sqlstate '45000' set MESSAGE_TEXT = 'No se puede insertar un valor en QR_Interno si QR_Externo ya tiene valor';
end if;
if (new.QR_Externo is not null and new.QR_Interno is not null) then
signal sqlstate '45000' set MESSAGE_TEXT = 'No se puede insertar un valor en QR_Externo si QR_Interno ya tiene valor';
end if;
END $$
DELIMITER ;
Componentes de hardware
Para conectar el RPi a una cerradura electromagnética se necesitarán los siguientes componentes y hardware:
- Raspberry Pi 4 Model B +
- Cerradura Electromagnética
- Módulo de escaneo de código QR integrado
- Relé (Parallax 12V Relay Board)
- Fuente de alimentación 5V (Raspberry Pi 15W USB-C Power Supply)
- Fuente de alimentación 12V
Esquema
Plan de implementación
Fase 1 - Configuración de Raspberry Pi
Instalar sistema operativo
Descargar Raspberry Pi Imager
La forma más sencilla de instalar Raspberry Pi OS en una tarjeta microSD es utilizar la herramienta Raspberry Pi Imager.
Este programa se puede descargar desde rpf.io/downloads.
La aplicación Raspberry Pi Imager está disponible para Windows, macOS y Ubuntu Linux, así que elija la versión correspondiente a su sistema.
Escribir el sistema operativo en la tarjeta microSD
Conecta la tarjeta microSD al ordenador. Se necesitará un adaptador USB para tarjetas microSD. La tarjeta no necesita ser pre-formateada.
Se inicia la aplicación Raspberry Pi Imager:
Se hace clic en el botón 'Choose OS' para seleccionar qué sistema operativo se desea instalar.
La opción superior es el Raspberry Pi OS estándar; si se quiere la versión reducida Lite o la versión completa (con todo el software recomendado preinstalado), se selecciona "Raspberry Pi OS (otro)".
También hay opciones para instalar LibreELEC (elegir la versión para el modelo de Raspberry Pi) y Ubuntu Core o Server.
Por último, hacer clic en el botón "Escribir" y esperar mientras la utilidad escribe el sistema operativo seleccionado en su tarjeta y lo verifica.
Cuando haya terminado, se puede extraer la tarjeta microSD. A continuación, se puede insertar en el Raspberry Pi y arrancarla con el sistema operativo que acabas de instalar.
Fase 2 - Configuración del programa de Python
Módulos
Los módulos que se usarán en el programa se encuentran en la carpeta “requirements.txt" Instalar los módulos en otro entorno
En caso de querer instalar los módulos en otro entorno:
Se Copia el archivo requirements.txt en la carpeta del dónde se almacena el proyecto.
Luego se ejecuta el siguiente comando:
pip install -r .\requirements.txt
Añadir nuevos módulos a la carpeta requirements.txt
En caso de instalar un módulo dentro del entorno virtual (env), se tiene que ejecutar el siguiente comando:
pip freeze > requirements.txt
Configurando el Entorno Virtual con Python
El Entorno Virtual es un entorno cooperativamente aislado de ejecución que permite a los usuarios de python y a las aplicaciones instalar y actualizar paquetes de distribución de python sin interferir con el comportamiento de otras aplicaciones de python en el mismo sistema.
Creando el entorno virtual
- Para crear el entorno virtual ejecutar el siguiente comando:
python -m venv env
Entrar al entorno virtual
- En Windows:
En el PowerShell ejecutar:
.\env\Scripts\activate
Salir del entorno virtual:
- En Windows:
En el PowerShell ejecutar:
env (ruta del proyecto) > deactivate
Variable de entorno
- Crea un archivo “.env”
El archivo “.env” almacena las variables de entorno para luego ser usado en la conexión a la base de datos.
El archivo se crea dentro de \boundary
Ejemplo de cómo debería verse el archivo “.env”:
La estructura de cómo debería estar las carpetas en el proyecto es la siguiente:
boundary/
- Models: Representa la forma de los datos y el encargado del mapeo
- DBConnector: Configuración de DB, conexión
- .env: Almacena las variables de entorno
control/
- DB_query: Definición de consulta de DB
entidad/
- Scan: Escanea el código qr y abre la puerta.
Fase 3 - Alojamiento de servidor web
- Hacer click en “Crear un recurso”.
- Crear una base de datos MySQL: Desde el portal de Azure, busque "Azure Database for MySQL Flexible Server" y seguir las instrucciones para crear una nueva base de datos.
Página web
En el portal de Azure buscar “Aplicación web” y luego seguir las instrucciones para crear una aplicación web.
Fase 4 - Instalación del hardware
Conexión del Raspberry Pi 4 Model B + a la cerradura electromagnética
El primer paso es identificar el pin GPIO que se utilizará para controlar el relé. En este caso para numerar los pines de la Raspberry Pi se utiliza la notación GPIO.
El segundo paso es conectar los pines 2 (5V) y 6 (GND) de la Raspberry Pi a la fuente de alimentación y tierra, respectivamente. Luego, es necesario conectar la terminal de señal (S) del relé al pin 11 – GPIO 17 para permitir el control del relé desde la Raspberry Pi.
A continuación, se muestra el paso 1 y 2 en la siguiente imagen:
Ilustración - Conexión GPIO al relé
El tercer paso es conectar el cable positivo de la fuente de alimentación a la terminal central del relé, que se identifica como el conector común (COM). Esto permitirá que la energía fluya a través del relé y hacia la cerradura electromagnética.
Por último, es necesario conectar la conexión positiva de la cerradura electromagnética a la terminal normalmente cerrada (NC) del relé y conectar el cable de tierra de la fuente de alimentación al cable de tierra de la cerradura electromagnética. De esta manera, se cierra el circuito de la cerradura electromagnética y se le proporciona la energía necesaria para funcionar.
Ilustración 2 Conexión del GPIO, relé y la cerradura electromagnética
Conexión del módulo de escaneo de código QR integrado al Raspberry Pi 4 Model B +
Para conectar la Raspberry Pi al módulo de escaneo de código QR integrado, la conexión puede ser por medio de USB o UART.
Conexión UART:
EL módulo de escaneo de código QR integrado incluye un cable llamado UART TTL (9-pin 4-wire). La Conexión de los pines debe realizarse como muestra la tabla a continuación:
UART TTL (9-pin 4-wire) | Raspberry Pi 4 model B+ |
---|---|
Cable rojo - 5V | Pin 4 - 5V |
Cable negro – GND | Pin 39 - GND |
Cable blanco – RX | Pin 8 - (GPIO 14) (TX) |
Cable verde – TX | Pin 10 - (GPIO 15) (RX) |
Ilustración 3 Conexión raspberry pi 4 al módulo de escaneo de código QR integrado
Conexión USB:
Los pasos para conectar el Raspberry Pi al módulo de escaneo por USB son los siguientes:
Conectar el módulo de escaneo de código QR a la Raspberry Pi a través de un cable USB.
Abrir una terminal en la Raspberry Pi e ingresar el siguiente comando para verificar si el módulo de escaneo está conectado correctamente:
lsusb
Ilustración 4 Esquema del sistema - Raspberry pi 4 al módulo de escaneo de código QR integrado por USB
Ilustración - Esquema del sistema - raspberry pi 4 al módulo de escaneo de código QR integrado por UART
Fase 5 – Instalación de la Cerradura electromagnética
Dependiendo del modelo, la cerradura electromagnética puede tener dos cables o cuatro y puede funcionar con 12 V o 24 V.
Guía de instalación de la cerradura electromagnética P200