7 – Creación del servidor central de recogida y visualización de sensores

🎧 Resumen en audio del tema
Escucha este breve audio para repasar las ideas principales de la tarea antes de continuar o al finalizar la lectura.

Introducción

Hasta este momento, varias Raspberry Pi del proyecto RaspyAlarma ya son capaces de leer información de sensores y almacenarla en una base de datos local. Ese primer paso permite que cada nodo funcione de manera autónoma y conserve sus propias lecturas.

Ahora vamos a dar el siguiente salto: construir un servidor central que reciba los datos generados por todas las Raspberry y los almacene en una base de datos general. A partir de esa información centralizada, desarrollaremos también una interfaz web que permita consultar el estado de todos los sensores, visualizar gráficas, detectar alertas y disponer de un histórico común.

Aunque en un sistema real normalmente existiría un único servidor central, en esta práctica se permitirá que el alumnado trabaje de forma flexible: pueden hacerlo individualmente o en grupos, e incluso pueden desplegar más de un servidor central para repartir tareas y favorecer la participación.

Reto del proyecto

Debéis construir el servidor central del sistema RaspyAlarma. Este servidor se ejecutará en una máquina virtual Ubuntu alojada en Proxmox y será el encargado de recibir, almacenar y mostrar las lecturas de sensores enviadas por distintas Raspberry Pi.

Cada Raspberry seguirá guardando sus datos en local, pero además tendrá que sincronizar los registros pendientes con la base de datos central. A partir de esta información, deberéis desarrollar una interfaz web que permita visualizar el estado de todos los sensores, consultar históricos y representar gráficas.

El objetivo no es solo almacenar datos, sino crear una arquitectura distribuida funcional, organizada y ampliable, similar a la que podría utilizarse en un entorno profesional real.


Objetivos del proyecto

Al finalizar esta práctica, el alumnado deberá ser capaz de:

  • Desplegar una máquina virtual Ubuntu en Proxmox que actuará como servidor central.
  • Instalar y configurar en ella los servicios necesarios.
  • Diseñar una base de datos central para almacenar las lecturas de todas las Raspberry.
  • Implementar un mecanismo para recibir datos desde los nodos remotos.
  • Guardar las lecturas recibidas en una base de datos general.
  • Crear una interfaz web para visualizar la información agregada.
  • Mostrar listados, filtros, estados de alerta y gráficas.
  • Comprender la diferencia entre almacenamiento local en nodos y centralización de información.
  • Simular una arquitectura real de monitorización distribuida.

Escenario de trabajo

Imaginad que habéis diseñado un sistema de asistencia y monitorización distribuido. Cada Raspberry Pi recoge lecturas de sensores instalados en distintos puntos y almacena esos datos localmente. Sin embargo, eso no es suficiente para gestionar el sistema completo.

Necesitamos un centro de control, una máquina central capaz de:

  • Recibir información desde todas las Raspberry.
  • Unificar los datos en una sola base de datos.
  • Mostrar el estado general del sistema.
  • Generar paneles visuales con tablas y gráficas.
  • Identificar situaciones de alerta.
  • Servir como base para futuras ampliaciones, como envío de correos, paneles de incidencias o integración con otros sistemas.

Arquitectura propuesta

La arquitectura recomendada para esta práctica será la siguiente:

Nodo Raspberry Pi

Cada Raspberry:

  • Lee sensores localmente.
  • Guarda sus lecturas en su propia base de datos.
  • Identifica qué registros todavía no han sido enviados al servidor central.
  • Envía únicamente esos registros pendientes.
  • Marca los registros como enviados cuando el servidor central los confirma.

Servidor central Ubuntu

La máquina virtual Ubuntu:

  • Ejecuta Apache o Nginx.
  • Ejecuta PHP para la parte web y la recepción de datos.
  • Ejecuta MariaDB o MySQL para almacenar todas las lecturas.
  • Expone una ruta o endpoint para recibir los datos enviados por las Raspberry.
  • Ofrece un panel web para visualizar y analizar la información.

Idea importante de diseño

Aunque técnicamente se podría hacer que el servidor central se conecte a las bases de datos de las Raspberry y “tire” de los datos, no es la opción recomendada para esta práctica.

La mejor solución didáctica y técnica es esta:

  • La Raspberry guarda sus lecturas en local.
  • La Raspberry envía periódicamente los registros pendientes al servidor central.
  • El servidor central responde confirmando la recepción.
  • La Raspberry marca esos registros como enviados.

Este enfoque tiene varias ventajas:

  • Es más realista.
  • Es más seguro.
  • Evita abrir las bases de datos de las Raspberry al exterior.
  • Reduce problemas de conectividad.
  • Permite trabajar con sincronización parcial y tolerancia a fallos.

Requisitos de la práctica

El sistema deberá cumplir, como mínimo, con los siguientes requisitos.

En el servidor central

  • Máquina virtual Ubuntu funcionando en Proxmox.
  • IP fija o localizable dentro de la red.
  • Apache + PHP + MariaDB instalados.
  • Base de datos central creada.
  • Endpoint de recepción de datos funcionando.
  • Interfaz web operativa.

En las Raspberry

  • Base de datos local con lecturas ya almacenadas.
  • Script de sincronización hacia el servidor central.
  • Uso de un identificador único de Raspberry.
  • Campo que indique si el registro ya fue enviado.
  • Capacidad para reenviar registros pendientes si hubo error.

Tecnologías recomendadas

Para esta práctica se recomienda utilizar:

  • Proxmox para alojar la máquina virtual.
  • Ubuntu Server como sistema operativo del servidor central.
  • Apache como servidor web.
  • PHP para el desarrollo del endpoint y del panel web.
  • MariaDB/MySQL como sistema gestor de base de datos.
  • Python en las Raspberry para el envío de datos.
  • Cron para automatizar los envíos periódicos.
  • Chart.js para representar gráficas en la interfaz web.

Parte 1 – Creación del servidor central

Paso 1. Crear la máquina virtual en Proxmox

Cada grupo o alumno deberá crear una máquina virtual Ubuntu en Proxmox que actuará como servidor central.

Características recomendadas

  • 2 vCPU
  • 2 GB o 4 GB de RAM
  • 20 GB de disco
  • Ubuntu Server
  • Adaptador de red en la misma red que las Raspberry

Tareas

  • Crear la VM.
  • Instalar Ubuntu Server.
  • Configurar nombre del equipo.
  • Configurar acceso por usuario y contraseña.
  • Anotar la IP asignada.

Recomendación

Es buena idea asignar una IP fija o una reserva DHCP, para que las Raspberry sepan siempre a qué dirección enviar los datos.


Paso 2. Actualizar el sistema

Una vez instalada la VM, actualizad el sistema:

sudo apt update && sudo apt upgrade -y

Paso 3. Instalar los paquetes necesarios

Instalad los componentes del servidor central:

sudo apt install apache2 mariadb-server php libapache2-mod-php php-mysql php-json php-mbstring -y

Comprobad que Apache está funcionando:

sudo systemctl status apache2

Comprobad también MariaDB:

sudo systemctl status mariadb

Paso 4. Preparar la base de datos central

Acceded a MariaDB:

sudo mysql

Cread la base de datos general del proyecto. Por ejemplo:

CREATE DATABASE raspialarma_central;

Después, cread un usuario específico para la aplicación:

CREATE USER 'raspyadmin'@'localhost' IDENTIFIED BY 'TuPasswordSegura';
GRANT ALL PRIVILEGES ON raspialarma_central.* TO 'raspyadmin'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Parte 2 – Diseño de la base de datos central

Paso 5. Crear la tabla principal de lecturas

La tabla central debe recoger información común de todas las Raspberry y de todos los sensores.

Estructura recomendada

USE raspialarma_central;CREATE TABLE lecturas_centrales (
id INT AUTO_INCREMENT PRIMARY KEY,
id_raspberry VARCHAR(100) NOT NULL,
nombresensor VARCHAR(100) NOT NULL,
lectura1 VARCHAR(100),
lectura2 VARCHAR(100),
lectura3 VARCHAR(100),
fecha_hora DATETIME NOT NULL,
alumnoEncargado VARCHAR(100),
descripcionSensor TEXT,
estado_alerta VARCHAR(50) DEFAULT 'normal',
fecha_recepcion TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
origen_ip VARCHAR(100),
hash_registro VARCHAR(255),
UNIQUE KEY unique_registro (id_raspberry, nombresensor, fecha_hora, hash_registro)
);

Explicación de algunos campos importantes

id_raspberry

Identifica de forma única de qué Raspberry procede el dato.

estado_alerta

Permite saber si la lectura está en estado normal, aviso o alerta.

fecha_recepcion

Indica cuándo llegó el registro al servidor central.

origen_ip

Puede almacenar la IP desde la que se envió el dato.

hash_registro

Sirve para evitar duplicados si una Raspberry vuelve a mandar el mismo dato.


Mejora interesante

También podéis crear una tabla de nodos Raspberry:

CREATE TABLE raspberries (
    id INT AUTO_INCREMENT PRIMARY KEY,
    id_raspberry VARCHAR(100) UNIQUE NOT NULL,
    nombre VARCHAR(100),
    ubicacion VARCHAR(100),
    descripcion TEXT,
    ultima_conexion DATETIME,
    estado VARCHAR(50) DEFAULT 'activo'
);

Esto os permitirá saber qué nodos existen, cuál fue su última conexión y tener una visión más ordenada del sistema.


Parte 3 – Recepción de datos en el servidor central

Paso 6. Crear el endpoint de recepción

En el servidor Ubuntu, cread una carpeta para vuestra aplicación:

sudo mkdir -p /var/www/html/raspialarma
sudo chown -R $USER:$USER /var/www/html/raspialarma

Dentro de esa carpeta, cread un archivo llamado por ejemplo:

recibir_datos.php

Este archivo actuará como punto de recepción de datos enviados desde las Raspberry.


¿Cómo funcionará?

La idea es que cada Raspberry envíe una petición HTTP POST al servidor central con los datos pendientes. El servidor:

  • Recibe la información.
  • La valida.
  • La inserta en la base de datos central.
  • Devuelve una respuesta indicando si el envío fue correcto.

Formato de envío recomendado

Podéis trabajar en JSON. Por ejemplo, una Raspberry podría enviar algo parecido a esto:

{
"id_raspberry": "raspi-aula-01",
"lecturas": [
{
"nombresensor": "temperatura",
"lectura1": "24.5",
"lectura2": null,
"lectura3": null,
"fecha_hora": "2026-04-21 10:15:00",
"alumnoEncargado": "Ana",
"descripcionSensor": "Sensor de temperatura laboratorio",
"estado_alerta": "normal",
"hash_registro": "abc123"
}
]
}

Qué debe hacer el endpoint

El archivo recibir_datos.php deberá:

  • Leer el JSON recibido.
  • Comprobar que el identificador de Raspberry existe.
  • Recorrer todas las lecturas recibidas.
  • Insertarlas en la tabla central.
  • Evitar duplicados.
  • Devolver una respuesta JSON con el resultado.

Respuesta recomendada

{
"status": "ok",
"insertados": 5,
"duplicados": 1
}

Mejora recomendable de seguridad

Para que no cualquier equipo mande datos falsos, podéis añadir una clave compartida o token simple.

Por ejemplo, que cada Raspberry envíe también:

  • api_key
  • o una cabecera personalizada

Y el servidor compruebe que coincide con la esperada.

No hace falta complicarlo demasiado: para una práctica educativa, una clave sencilla ya es suficiente para introducir el concepto de autenticación entre máquinas.


Parte 4 – Sincronización desde las Raspberry

Paso 7. Adaptar el script Python de cada Raspberry

Cada Raspberry ya guarda datos en local. Ahora deberá además:

  • Consultar en su base de datos local los registros no enviados.
  • Preparar un JSON con esos registros.
  • Enviarlo al servidor central.
  • Si el servidor responde correctamente, marcar esos registros como enviados.

Lógica del proceso

El flujo correcto debería ser este:

  1. La Raspberry lee el sensor.
  2. Inserta la lectura en su base local.
  3. Cada cierto tiempo, otro script consulta los registros con enviado_central = 0.
  4. Los envía al servidor central.
  5. Si el servidor responde correctamente, esos registros pasan a enviado_central = 1.

Campo obligatorio en la base local

Recordad que la tabla local de cada Raspberry debe incluir algo como:

  • id_raspberry
  • estado_alerta
  • enviado_central

Esto permitirá gestionar la sincronización correctamente.


Frecuencia de envío

Podéis programar el script para que se ejecute con cron cada:

  • 1 minuto
  • 5 minutos
  • o el intervalo que considere el grupo

Eso dependerá del ritmo de captura de datos.


Parte 5 – Interfaz web del servidor central

Paso 8. Crear el panel web principal

Una vez que el servidor central ya recibe datos, habrá que crear una web que muestre toda la información agregada.

La interfaz deberá desarrollarse en PHP y deberá leer los datos desde la base de datos central.


Contenido mínimo del panel

El panel debería mostrar, como mínimo:

Vista general

  • Número total de lecturas recibidas.
  • Número de Raspberry activas.
  • Número de sensores registrados.
  • Número de alertas.

Tabla de lecturas

  • ID
  • Raspberry origen
  • Nombre del sensor
  • Lecturas
  • Fecha y hora
  • Estado de alerta

Filtros

  • Filtrar por Raspberry
  • Filtrar por sensor
  • Filtrar por fecha
  • Filtrar por estado de alerta

Gráficas

  • Evolución temporal de un sensor
  • Número de alertas por nodo
  • Distribución de lecturas por tipo de sensor

Paso 9. Crear una portada tipo dashboard

Una buena práctica es construir una página principal con tarjetas o bloques visuales.

Ejemplo de bloques

  • Total de nodos conectados
  • Última lectura recibida
  • Sensores en alerta
  • Total de registros

Esto hace que el proyecto parezca mucho más profesional y permite al alumnado trabajar el diseño de interfaces orientadas a monitorización.


Paso 10. Crear gráficas con Chart.js

Para representar datos de forma visual, se recomienda utilizar Chart.js.

Ejemplos de gráficas que podéis pedir:

  • Temperatura a lo largo del tiempo
  • Número de lecturas por Raspberry
  • Estados de alerta por tipo de sensor
  • Comparativa entre varios nodos

Paso 11. Crear una página de detalle por Raspberry

Además del panel general, es muy interesante que exista una vista individual para cada Raspberry.

Esa página podría mostrar:

  • Identificador del nodo
  • Ubicación
  • Última conexión
  • Sensores asociados
  • Histórico de lecturas
  • Alertas detectadas

Esto da una estructura mucho más completa al proyecto.


Parte 6 – Funcionalidades extra recomendadas

Aquí es donde puedes enriquecer muchísimo el proyecto.

1. Sistema de alertas visuales

Si una lectura supera un umbral, mostrarla en rojo o destacarla visualmente.

Ejemplos:

  • Temperatura demasiado alta
  • Humedad anómala
  • Falta de actualización de un nodo

2. Detección de Raspberry inactivas

Si una Raspberry no envía datos en un tiempo determinado, el panel puede marcarla como:

  • Activa
  • Inactiva
  • Desconectada

Esto es muy útil en un sistema distribuido real.


3. Registro de logs

Crear una tabla o archivo de log donde quede constancia de:

  • Envíos recibidos
  • Fallos de sincronización
  • Intentos inválidos
  • Errores de base de datos

Así introducís el concepto de auditoría del sistema.


4. Histórico de incidencias

Podéis añadir una tabla para guardar incidencias detectadas:

  • Fecha
  • Raspberry
  • Tipo de problema
  • Descripción
  • Estado de resolución

5. Exportación de datos

Añadir una opción para exportar lecturas en CSV.

Esto da mucho valor al proyecto porque permite luego tratar la información en Excel, LibreOffice Calc o herramientas de análisis.


6. Panel responsive

Hacer que la web se vea razonablemente bien en móvil, tablet y PC.


7. Inicio de sesión

Como ampliación, podéis pedir una pequeña autenticación en PHP para que el panel central no sea público.


8. Mapa o distribución física

Si queréis darle más fuerza visual, podéis representar cada Raspberry por ubicación o sala.



Entregables

Entregable 1 – Infraestructura

Documento con:

  • Nombre del servidor
  • IP
  • Capturas de la VM
  • Servicios instalados

Entregable 2 – Base de datos

  • Script SQL de creación
  • Explicación de tablas
  • Justificación del diseño

Entregable 3 – Recepción de datos

  • Código del endpoint
  • Ejemplo de JSON recibido
  • Capturas de pruebas correctas

Entregable 4 – Sincronización

  • Script Python de envío
  • Consulta de pendientes
  • Marcado de enviados

Entregable 5 – Panel web

  • Capturas del dashboard
  • Tablas
  • Filtros
  • Gráficas

Entregable 6 – Mejoras

  • Seguridad
  • Logs
  • Alertas
  • Exportación
  • Detección de nodos inactivos

Criterios de evaluación orientativos

Puedes evaluarlo así:

Diseño de arquitectura

  • Claridad del planteamiento
  • Separación entre nodo y central
  • Coherencia técnica

Base de datos

  • Estructura correcta
  • Uso de claves
  • Evitar duplicados
  • Campos útiles

Comunicación entre sistemas

  • Envío correcto de datos
  • Gestión de errores
  • Registros marcados como enviados

Interfaz web

  • Funcionalidad
  • Claridad visual
  • Utilidad de filtros
  • Gráficas correctas

Mejoras

  • Seguridad
  • Alertas
  • Logs
  • Exportación
  • Control de nodos

Documentación

  • Orden
  • Explicaciones
  • Capturas
  • Comprensión real del sistema

Resultado final esperado

Al terminar la práctica, el alumnado habrá construido un sistema completo con esta lógica:

  • Varias Raspberry recogen datos.
  • Cada una los almacena localmente.
  • Cada una sincroniza con el servidor central.
  • El servidor central unifica la información.
  • Un panel web muestra todo el sistema de manera visual y organizada.

En otras palabras, no habrán hecho solo una página PHP, sino una infraestructura distribuida de monitorización, que ya se parece bastante a una solución profesional real.


Ampliaciones que puedes realizar

Esto te puede venir bien para futuras fases del proyecto:

Envío de correos de alerta

Cuando un sensor entre en estado crítico, enviar correo automático.

API REST real

En lugar de un PHP simple, crear una pequeña API con rutas más organizadas.

Panel de administración

Permitir alta de nodos, edición de sensores y gestión de incidencias.

Copias de seguridad

Programar backups automáticos de la base de datos central.