Contenido
- Parte 1. Crear la base de datos
- Parte 2. Crear la tabla común del proyecto
- Parte 3. Crear un usuario específico para la aplicación
- Parte 4. Crear la estructura de carpetas
- Parte 5. Instalar el conector de Python para MariaDB
- Parte 6. Crear primero un script de prueba con datos fijos
- Paso 4. Ejecutar el script manualmente
- Parte 7. Comprobar que el INSERT ha funcionado
- Parte 8. Sustituir los datos fijos por la lectura real del sensor
- Parte 9. Cómo decidir el estado de alerta
- Parte 10. Valor inicial de enviado_central
- Parte 11. Ejemplo de script con lógica de alerta
- Parte 12. Automatizar la ejecución con cron
- Parte 13. Consultas útiles para revisar la información
En esta práctica vas a convertir tu Raspberry Pi en un pequeño nodo autónomo de captura de datos dentro del proyecto RaspyAlarma.
Tu Raspberry deberá ser capaz de:
- leer los datos de un sensor con Python,
- guardar esas lecturas en una base de datos MariaDB,
- ejecutar ese proceso automáticamente cada cierto tiempo mediante cron,
- y dejar preparada la información para una futura sincronización con un servidor central.
Todos los alumnos deberán usar la misma estructura de base de datos, ya que más adelante será necesario unificar los datos de todos los sensores y de todas las Raspberry del proyecto.
Objetivo general
El objetivo de esta práctica es crear un sistema automático en el que una Raspberry:
- lea un sensor,
- almacene la lectura en una base de datos local,
- identifique de qué Raspberry procede el dato,
- indique si la lectura representa o no una situación de alerta,
- y marque si ese dato ya fue enviado o no al servidor central.
Estructura obligatoria de la base de datos
Todos los alumnos deberán usar una base de datos llamada exactamente:
raspialarm
Y una tabla llamada exactamente:
lecturas_sensores
Estructura obligatoria de la tabla
La tabla deberá contener estos campos:
idraspberry_idnombresensorlectura1lectura2lectura3fecha_horaalumnoEncargadodescripcionSensorestado_alertaenviado_central
Significado de los campos
raspberry_id
Este campo servirá para identificar qué Raspberry ha generado la lectura.
Ejemplos válidos:
RPI01RPI_AULA_01RPI_PASILLORPI_HABITACION_3
Este identificador debe ser fijo para cada Raspberry y no debe cambiar entre ejecuciones.
estado_alerta
Este campo servirá para indicar el estado de la lectura.
Valores recomendados:
normalavisocritico
No todos los sensores tendrán alertas complejas al principio, pero el campo debe existir ya desde esta fase.
Ejemplo:
- una lectura dentro de lo normal →
normal - una lectura elevada pero no crítica →
aviso - una lectura peligrosa o fuera de umbral →
critico
enviado_central
Este campo servirá para saber si esa lectura ya ha sido enviada al servidor central del proyecto.
Valores recomendados:
0→ todavía no se ha enviado1→ ya se ha enviado
En esta práctica, normalmente todos los registros nuevos se guardarán inicialmente con valor 0.
Parte 1. Crear la base de datos
Paso 1. Comprobar que MariaDB está activa
Abre una terminal y ejecuta:
sudo systemctl status mariadb
Si no estuviera arrancada:
sudo systemctl start mariadb
Y para dejarla activada al iniciar el sistema:
sudo systemctl enable mariadb
Paso 2. Entrar en MariaDB
sudo mariadb
Paso 3. Crear la base de datos
Dentro de MariaDB:
CREATE DATABASE raspialarm;
SHOW DATABASES;
USE raspialarm;
Parte 2. Crear la tabla común del proyecto
Ejecuta esta instrucción SQL exactamente como aparece:
CREATE TABLE lecturas_sensores (
id INT AUTO_INCREMENT PRIMARY KEY,
raspberry_id VARCHAR(50) NOT NULL,
nombresensor VARCHAR(100) NOT NULL,
lectura1 DECIMAL(10,2),
lectura2 DECIMAL(10,2),
lectura3 DECIMAL(10,2),
fecha_hora DATETIME NOT NULL,
alumnoEncargado VARCHAR(100) NOT NULL,
descripcionSensor VARCHAR(255),
estado_alerta VARCHAR(20) NOT NULL DEFAULT 'normal',
enviado_central TINYINT(1) NOT NULL DEFAULT 0
);
Paso 4. Comprobar la estructura de la tabla
DESCRIBE lecturas_sensores;
También puedes verla completa con:
SHOW CREATE TABLE lecturas_sensores;
Parte 3. Crear un usuario específico para la aplicación
No debes usar root dentro del script Python.
Ejecuta:
CREATE USER 'raspiuser'@'localhost' IDENTIFIED BY 'raspi1234';
GRANT ALL PRIVILEGES ON raspialarm.* TO 'raspiuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Parte 4. Crear la estructura de carpetas
Ejecuta:
mkdir -p /home/pi/raspialarma/sensores
mkdir -p /home/pi/raspialarma/logs
mkdir -p /home/pi/raspialarma/docs
Comprueba el resultado:
ls -R /home/pi/raspialarma
Parte 5. Instalar el conector de Python para MariaDB
Ejecuta:
sudo apt update
sudo apt install python3-pip python3-mysqldb -y
Parte 6. Crear primero un script de prueba con datos fijos
Antes de leer el sensor real, primero debes comprobar que:
- Python puede conectarse a MariaDB,
- el
INSERTfunciona, - y las nuevas columnas también se guardan correctamente.
Edita el archivo:
nano /home/pi/raspialarma/sensores/captura_sensor.py
Pega este contenido:
#!/usr/bin/env python3
import MySQLdb
from datetime import datetime
def escribir_log(mensaje):
with open("/home/pi/raspialarma/logs/raspialarma.log", "a") as log:
log.write(f"{datetime.now()} - {mensaje}\n")
try:
conexion = MySQLdb.connect(
host="localhost",
user="raspiuser",
passwd="raspi1234",
db="raspialarm"
)
cursor = conexion.cursor()
raspberry_id = "RPI01"
nombresensor = "SENSOR_PRUEBA"
lectura1 = 25.50
lectura2 = 60.00
lectura3 = 0.00
fecha_hora = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
alumnoEncargado = "TU_NOMBRE"
descripcionSensor = "Prueba inicial de inserción en MariaDB"
estado_alerta = "normal"
enviado_central = 0
sql = """
INSERT INTO lecturas_sensores
(raspberry_id, nombresensor, lectura1, lectura2, lectura3, fecha_hora,
alumnoEncargado, descripcionSensor, estado_alerta, enviado_central)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
valores = (
raspberry_id,
nombresensor,
lectura1,
lectura2,
lectura3,
fecha_hora,
alumnoEncargado,
descripcionSensor,
estado_alerta,
enviado_central
)
cursor.execute(sql, valores)
conexion.commit()
mensaje = "Lectura guardada correctamente."
print(mensaje)
escribir_log(mensaje)
except Exception as e:
error = f"Error: {e}"
print(error)
escribir_log(error)
finally:
try:
cursor.close()
conexion.close()
except:
pass
El INSERT debe hacerse desde Python
En esta práctica no se insertarán datos desde PHP ni desde formularios web.
La inserción de datos se realizará directamente desde un script Python.
El script debe ejecutarse automáticamente
El script Python deberá ejecutarse cada cierto tiempo utilizando cron.
Debes documentar lo que significa cada lectura
Cada sensor es diferente. Por tanto, deberás dejar claro en tu documentación qué representa:
lectura1lectura2lectura3
Por ejemplo, en un DHT11 podrían significar:
lectura1= temperaturalectura2= humedadlectura3= no usada
Posible estructura de significado de las lecturas
Para que todos trabajen de forma homogénea, puedes pedirles una tabla como esta en su documentación:
| Tipo de sensor | lectura1 | lectura2 | lectura3 |
|---|---|---|---|
| DHT11 / DHT22 | Temperatura | Humedad | No usada |
| HC-SR04 | Distancia | No usada | No usada |
| PIR | Movimiento detectado (0/1) | No usada | No usada |
| MQ-2 | Nivel de gas/humo | Umbral | No usada |
| LDR | Intensidad de luz | No usada | No usada |
Paso 2. Personalizar el script
Debes modificar al menos estos valores:
raspberry_id = "RPI01"
alumnoEncargado = "TU_NOMBRE"
Sustitúyelos por valores reales.
Ejemplo:
raspberry_id = "RPI_AULA_03"
alumnoEncargado = "Antonio"
Paso 3. Dar permisos de ejecución
chmod +x /home/pi/raspialarma/sensores/captura_sensor.py
Paso 4. Ejecutar el script manualmente
python3 /home/pi/raspialarma/sensores/captura_sensor.py
Si todo ha ido bien, verás:
Lectura guardada correctamente.
Parte 7. Comprobar que el INSERT ha funcionado
Entra en MariaDB:
mariadb -u raspiuser -p
Contraseña:
raspi1234
Dentro de MariaDB:
USE raspialarm;
SELECT * FROM lecturas_sensores;
Comprueba que aparecen correctamente:
raspberry_idestado_alertaenviado_central
Parte 8. Sustituir los datos fijos por la lectura real del sensor
Cuando el script de prueba funcione, sustituye los valores fijos por los datos reales del sensor.
La tabla seguirá siendo la misma.
Solo cambiarán los valores que insertas.
Parte 9. Cómo decidir el estado de alerta
Debes programar una lógica sencilla para determinar el valor de estado_alerta.
Ejemplo general
if lectura1 < 30:
estado_alerta = "normal"
elif lectura1 < 50:
estado_alerta = "aviso"
else:
estado_alerta = "critico"
Esto es solo un ejemplo. Cada sensor deberá definir sus propios umbrales.
Ejemplos según sensor
Sensor de temperatura
- temperatura normal →
normal - temperatura alta →
aviso - temperatura muy alta →
critico
Sensor de gas
- valor bajo →
normal - valor elevado →
aviso - valor peligroso →
critico
Sensor PIR
- sin movimiento →
normal - movimiento detectado → puede mantenerse en
avisoocritico, según el criterio del proyecto
Sensor de distancia
- distancia segura →
normal - objeto cercano →
aviso - objeto muy cercano →
critico
Parte 10. Valor inicial de enviado_central
Todos los registros nuevos deberán guardarse inicialmente así:
enviado_central = 0
Esto significa que todavía no han sido enviados al servidor central.
Más adelante, cuando construyas el sistema de sincronización, los registros enviados se actualizarán a:
enviado_central = 1
Parte 11. Ejemplo de script con lógica de alerta
#!/usr/bin/env python3
import MySQLdb
from datetime import datetime
def escribir_log(mensaje):
with open("/home/pi/raspialarma/logs/raspialarma.log", "a") as log:
log.write(f"{datetime.now()} - {mensaje}\n")
try:
conexion = MySQLdb.connect(
host="localhost",
user="raspiuser",
passwd="raspi1234",
db="raspialarm"
)
cursor = conexion.cursor()
raspberry_id = "RPI01"
nombresensor = "SENSOR_PRUEBA"
lectura1 = 42.00
lectura2 = 0.00
lectura3 = 0.00
fecha_hora = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
alumnoEncargado = "TU_NOMBRE"
descripcionSensor = "Prueba con niveles de alerta"
enviado_central = 0
if lectura1 < 30:
estado_alerta = "normal"
elif lectura1 < 50:
estado_alerta = "aviso"
else:
estado_alerta = "critico"
sql = """
INSERT INTO lecturas_sensores
(raspberry_id, nombresensor, lectura1, lectura2, lectura3, fecha_hora,
alumnoEncargado, descripcionSensor, estado_alerta, enviado_central)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
valores = (
raspberry_id,
nombresensor,
lectura1,
lectura2,
lectura3,
fecha_hora,
alumnoEncargado,
descripcionSensor,
estado_alerta,
enviado_central
)
cursor.execute(sql, valores)
conexion.commit()
mensaje = f"Lectura guardada correctamente con estado {estado_alerta}"
print(mensaje)
escribir_log(mensaje)
except Exception as e:
error = f"Error: {e}"
print(error)
escribir_log(error)
finally:
try:
cursor.close()
conexion.close()
except:
pass
Parte 12. Automatizar la ejecución con cron
Edita el crontab:
crontab -e
Añade una de estas opciones.
Cada minuto
* * * * * /usr/bin/python3 /home/pi/raspialarma/sensores/captura_sensor.py >> /home/pi/raspialarma/logs/cron.log 2>&1
Cada 5 minutos
*/5 * * * * /usr/bin/python3 /home/pi/raspialarma/sensores/captura_sensor.py >> /home/pi/raspialarma/logs/cron.log 2>&1
Cada 10 minutos
*/10 * * * * /usr/bin/python3 /home/pi/raspialarma/sensores/captura_sensor.py >> /home/pi/raspialarma/logs/cron.log 2>&1
Parte 13. Consultas útiles para revisar la información
Ver todas las lecturas
SELECT * FROM lecturas_sensores;
Ver las últimas lecturas
SELECT * FROM lecturas_sensores ORDER BY fecha_hora DESC;
Ver solo lecturas de una Raspberry
SELECT * FROM lecturas_sensores
WHERE raspberry_id = 'RPI01';
Ver solo lecturas en estado crítico
SELECT * FROM lecturas_sensores
WHERE estado_alerta = 'critico';
Ver solo lecturas pendientes de enviar al servidor central
SELECT * FROM lecturas_sensores
WHERE enviado_central = 0;
Contar cuántas lecturas no se han enviado todavía
SELECT COUNT(*) AS pendientes
FROM lecturas_sensores
WHERE enviado_central = 0;







