Sie sind auf Seite 1von 30

ADI-e

Cmo almacenar los


datos obtenidos por los
dispositivos de la Internet
de las cosas (IoT)
PHP

Roberto RGL. Gabriel Lino


10/06/2016

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Cmo almacenar los datos obtenidos por los


dispositivos de la Internet de las cosas (IoT)
Este es el primero de una serie de artculos en los que se explican algunas de las
tcnicas ms usadas para almacenar la informacin que se obtiene con los
dispositivos conectados a la Internet de las cosas (IoT)
1. Usar un servidor web para Internet de las cosas
2. Almacenar datos en un servidor web IoT usando peticiones HTTP POST
3. Preparar la base de datos MySQL o MariaDB
4. Acceder a la base de datos desde el lenguaje de programacin PHP

Adems de todo esto, por si falla la red, siempre se puede conectar una tarjeta SD
por SPI y utilizarla generando un archivo de seguridad para grabar los datos en la
tarjeta SD cuando no haya acceso al servidor e incluso cuando haya acceso al
servidor para usar el documento creado como copia de respaldo.

Pgina 1 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Usar un servidor web para Internet de las cosas


(IoT)

Una de las constantes en los sistemas que dan soporte a la Internet de las cosas
son las bases de datos porque ofrecen, frente a la alternativa del almacenamiento
en bruto de la informacin o usando procedimientos de un nivel bajo, un mtodo
muy eficaz equilibrado en esfuerzo de instalacin, consumo de recursos
(procesador y memoria a corto y largo plazo) mantenimiento y rendimiento.
La manera ms comn de explotar la base de datos es conforme a una arquitectura
cliente-servidor. El dispositivo electrnico, el objeto de la Internet de las cosas,
actuara como cliente y se dispondra de un sistema autnomo, frecuentemente un
ordenador completo, trabajando como servidor de las bases de datos.
Hay multitud de formas de conectar con el sistema que soporta el servidor de bases
de datos (muchas de las cuales ya han sido discutidas en artculos anteriores) al
tratarse de un equipo de la Internet de las cosas parece que lo ms intuitivo es
pensar en una conexin de red remota (como GPRS o EDGE/EGPRS, por ejemplo)
o una local, seguramente WiFi, que posiblemente conecte a por medio de un
enrutador (router) a otra remota.
Como conectar directamente con la base de datos puede ser complejo y si se trata
de un sistema pblico hay que aadir otras cuestiones que pueden afectar a la
seguridad y al rendimiento, lo ms comn es acceder a la base de datos desde un
servidor web que, aunque seguramente limite un poco el rendimiento, aade una
capa al sistema que, aunque parezca una paradoja, hace ms sencilla la gestin.

Pgina 2 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

El sistema que con ms frecuencia se usa en estos trabajos (y es mayora en la


tecnologa web) es el basado en alguna distribucin Linux, ejecutando un servidor
Apache desde el que se puede acceder a un servidor de bases de datos MySQL o
MariaDB desde el lenguaje de programacin PHP. A esta configuracin se le suele
dar el nombre de LAMP por las siglas de los principales componentes. A estos
servidores es muy sencillo aadir en un sistema basado en GNU/Linux otros como
los de sincronizacin horaria o correo electrnico. Adems existen distribuciones
Linux para dispositivos mnimos (al estilo de la Raspberry Pi) con los que crear una
intranet de las cosas que pueda dar un servicio local completo o incluso conectar
y sincronizar informacin con otro remoto.
Por supuesto tambin existen versiones para usar otros sistemas operativos como
anfitriones, como WAMP para Windows o MAMP para Mac OS X. Entre otras, hay
dos ramas de desarrollo muy interesantes para WAMP muy populares, Bitnami
WAMP Stack y WAMP Server. Para usar MAMP, la opcin ms frecuente es MAMP
free y MAMP pro, la primera gratis y la segunda de pago.
Una opcin interesante a las anteriores es XAMPP que adems de ser libre y
multiplataforma incluye Perl y opta por MariaDB en lugar de MySQL. Ciertamente
nada que no se pueda hacer fcilmente con los repositorios de una distribucin
Linux convencional, por lo que parece que es la mejor alternativa sobre todo si se
trata de usar una mquina independiente (no la misma del escritorio) como servidor
web.
As que, aunque finalmente se ceda la gestin de los datos al servidor MySQL y se
pre-procese (y seguramente pos-procese) usando PHP, la conexin entre el
dispositivo electrnico y el servidor de bases de datos se realiza usando como
intermediario al servidor web y por tanto usando el protocolo HTTP (o si est
disponible su versin segura, por HTTPS) En el siguiente artculo de la serie se
explica cmo almacenar datos en un servidor web IoT usando peticiones HTTP
POST

Pgina 3 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Almacenar datos en un servidor web IoT


usando peticiones HTTP POST

Como se explicaba en el primer artculo de la serie almacenar los datos obtenidos


por los dispositivos de la internet de las cosas, aunque los datos que se guardan
terminan en un servidor MySQL o MariaDB y se utiliza el lenguaje PHP para
manipularlos a la entrada y a la salida, el flujo de informacin entre el equipo
electrnico y la base de datos se produce usando un servidor web con el que se
comunica segn el protocolo HTTP.
En los inicios de la definicin del protocolo HTTP se cont con usos equiparables al
que se est describiendo pero el hecho es que finalmente no se ha explotado por
completo por diversas razones, en parte de seguridad y en parte porque nunca se
avanz en la definicin de un protocolo ms especfico ni ms eficiente as que en
la actualidad, especialmente en los servidores pblicos, lo ms frecuente es usar
una conexin HTTP que hace una peticin POST al servidor para almacenar la
informacin o una GET para recuperarla, normalmente para mostrar una pgina
web que la presenta e incluso sobre la que se puede interactuar.
El texto ms bsico enviado al servidor en una peticin HTTP POST incluye una
lnea con el tipo de peticin (POST) la ruta hasta la pgina web que almacenar la
informacin y la versin del protocolo HTTP; otra lnea con el nombre del host (lo
que permite servidores virtuales en el mismo servidor y/o en la misma direccin IP)
y por fin otra que contiene los datos que se graban separados entre ellos por el
signo & y de las lneas anteriores por una en blanco.

Pgina 4 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

1 POST /iot/grabar_temperatura HTTP/1.1


2 Host: polaridad.es
3
4 ne=muelle+de+carga&tp=10.26&cr=2.18

En el ejemplo de arriba, un servidor llamado polaridad.es contendra una pgina en


/iot/grabar_temperatura para gestionar la informacin utilizando para comunicarse
la versin 1.1 del protocolo HTTP
Puede verse que se usan dos signos & lo que permite saber que se almacenan tres
campos. El nombre de los campos queda a la izquierda del signo igual y se han
usado slo dos letras para definirlos. Como el nombre de los campos (o variables,
si se prefiere) de la peticin HTTP no guardan relacin con los de la base de datos,
no es especialmente importante usar textos descriptivos y suelen elegirse nombres
breves (incluso campos numerados) para ahorrar texto en la comunicacin con el
servidor y aligerar el proceso de envo de datos.
Los datos que un dispositivo IoT enva normalmente al servidor son de tipo
numrico, principalmente enteros y decimales sencillos. Cuando se envan valores
en formato texto, como es el caso de la variable ne del ejemplo, pueden darse
circunstancias desfavorables que pueden resolverse, segn el caso, con ms o
menos xito y facilidad. En esta ocasin se usan signos ms (+) para separar las
palabras en sustitucin de los espacios que de otra forma alteraran la peticin
POST. Una forma genrica de enviar los datos que resuelve la mayora de los
casos es indicando el cdigo hexadecimal de los caracteres, precedidos por el
signo de porcentaje (%) Como es lgico, no conviene usar este recurso ms que
cuando lo codificado sea problemtico ya que se aumenta la longitud de lo enviado
lo que requiere en general ms recursos aunque ciertamente se trate de
dimensiones muy pequeas.
Aunque es posible hacer funcionar un servidor web para Internet de las cosas slo
con la informacin del ejemplo anterior, muchos servidores, especialmente los
pblicos, aaden otros datos a la consulta POST (por desgracia no siempre
limitados al protocolo) El ejemplo de abajo corresponde con la peticin post que
solicita el conocido servidor pblico para Internet de las cosas ThingSpeak.

Pgina 5 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

1 POST /update HTTP/1.1


2 Host: api.thingspeak.com
3 Connection: close
4 X-THINGSPEAKAPIKEY: 1234567890
5 Content-Type: application/x-www-form-urlencoded
6 Content-Length: 23
7
8 1=10.25&2=-5.32&3=25.15

Adems de algunos datos propios, como X-THINGSPEAKAPIKEY (y que corresponde con


el identificador de cada cliente) en el ejemplo anterior puede verse que hay otras
cabeceras que aaden ms informacin a la peticin.
La forma de usar una cabecera en una peticin POST consiste simplemente en
escribir su nombre, un signo de dos puntos (:) un espacio en blanco y el valor que
se le quiere asignar.
Para poder hacer pruebas de peticiones POST al servidor web antes de que
terminar la configuracin de los otros componentes puede establecerse una
conexin con servidor y enviar manualmente los datos. Por ejemplo, en un
ordenador con Linux bastara con usar telnet polaridad.es 80 siendo polaridad.es el
nombre del servidor y 80 el nmero de puerto en el que responde el servicio HTTP.

Pgina 6 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Tanto en Linux como en Windows o en OS X se puede usar la herramienta


multiplataforma PuTTY, de la que se habl en el artculo control de dispositivos
serie UART desde el ordenador, para realizar la conexin sin usar la consola.

En la siguiente lista de cabeceras HTTP estn la mayora de las que pueden


resultar tiles para una peticin POST a un servidor web para Internet de las cosas.

Accept

Sirve para indicar el tipo MIME que la peticin espera que el servidor
use en la respuesta. Se expresa como tipo/subtipo que puede generalizarse
utilizando como signo comodn el asterisco (*) por ejemplo como */* para
referirse a cualquiera o tipo/* para referirse a todos los subtipos de tipo

Pgina 7 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Los ms comnmente usados son:

text/plain

Aunque es el ms bsico tambin es el ms usado. Espera que el


servidor devuelva como respuesta un texto sencillo (plano) que es suficiente
para avisar de que la transaccin ha sido correcta y a lo sumo aadir
informacin accesoria como el nmero de orden de los datos grabados, el
resultado de una comparacin, la fecha del servidor
application/xml o text/xml Espera que el servidor responda a la peticin en
formatoXML. El sentido de elegir text en lugar de application permite una
lectura humana (frente a automtica) ms sencilla. Esta dualidad se
presentar e otros tipos MIME pero la tendencia a futuro del estndar es
preferir application frente a text. El formato XML permite estructurar de
manera muy slida una respuesta que contenga muchos datos, el
inconveniente es que aade mucho artificio a los datos netos, lo que hace
que la respuesta ocupe ms de lo imprescindible, necesite por tanto ms
ancho de banda y seguramente ms memoria en el dispositivo IoT para
procesarla.
text/html Se utiliza cuando la respuesta del servidor es HTML codificado
como texto sencillo (texto plano) normalmente formateando una respuesta.
Como se trata de almacenar datos y la respuesta llegara a un pequeo
dispositivo sin muchos recursos no es frecuente usar este tipo.
application/xhtml+xml Bsicamente se trata de la versin XHTML (HTML
como XML vlido) de la informacin del apartado anterior.
application/json. Es el ms usado cuando la respuesta del servidor contiene
varios datos incluyendo una estructura ms o menos compleja. El formato
JSON comparte con el formato XML una estructura slida y aade la ventaja
de ser ms escueto en el texto aadido por la estructura.
Accept-Charset Determina la codificacin de texto que se pide que se use en la
respuesta. Para codificar caracteres latinos suelen usarse el UTF-8, el ms
completo, ISO 8859-15, que incluye el signo del Euro () y el ISO 8859-1, que
es el ms bsico.
Accept-Encoding Indica el formato conforme al cual puede codificarse la
respuesta del servidor. Bsicamente sirve para indicar un tipo de compresin.
Algunos de los ms frecuentes son gzipdeflate (que puede especificarse con
ms detalle con deflate-raw o deflate-http) No es habitual usarlo en
pequeos dispositivos conectados a la Internet de las cosas ya que exige
cierto consumo de recursos (memoria y tiempo de proceso) que suelen ser
escasos en estos tipos de equipos. No es necesario indicar que no se usa la

Pgina 8 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

compresin con Accept-Encoding: identity ya que se considera tal


circunstancia por defecto.
Accept-Language Expresa el idioma que puede utilizarse en la respuesta. Por
ejemplo, el espaol de Espaa se especificara como es-ES o el ingls de los
Estados Unidos de Amrica como en-US
Connection Sirve para especificar lo que debe hacerse con la conexin que se
ha establecido entre el cliente (el dispositivo IoT) y el servidor web una vez
que se reciban los datos. Normalmente se usa con el valor close en el formato
Connection: close para indicar que la conexin debe cerrarse despus de
responder al cliente.
Content-Length Permite indicar el nmero de bytes que ocupa la parte de la
peticin que contiene los datos, que es la que va despus de las cabeceras y
separada por una lnea en blanco. Es muy til puesto que sirve para verificar
la integridad de la informacin que se enva; si no mide lo que se ha
declarado no se almacena ya que se considera que no ha llegado
correctamente. Suele ser exigida por la mayora de los servidores IoT
pblicos.
Content-Type Sirve para indicar el tipo MIME con el que se codifica la
informacin que se enva al servidor. Suelen utilizarse los tipos text/html
cuando se expresan como una lista de valores sencilla los datos que se
mandan al servidor (algo como a=3.6&b=4.8) y application/jsonrequest (que
sera el equivalente al tipo application/json del que se habla en Accept)
cuando es necesaria una estructura ms compleja, pero puede enviarse
cualquiera de la lista de tipos MIME.
Cookie Sirve para aadir un identificador de sesin con el que mantener una
cadena de transferencias (consulta, respuesta, consulta) ms compleja que
una nica peticin con la que enviar determinados datos relacionados pero
que se obtienen en diferentes momentos.
Referer URL que ha originado la peticin POST, por ejemplo la pgina web
desde la que se envan. En el caso de usarse para IoT no aade informacin
relevante ya que la informacin se enva directamente, sin una pgina previa,
as que no es frecuente usarla.
User-Agent Informa del dispositivo que realiza la peticin. En el trfico web
habitual se trata del navegador para usarse en Internet de las cosas permite
indicar al servidor el tipo de dispositivo electrnico que hace la peticin. Al
identificarse frente al servidor permite que la respuesta est formateada de
una forma diferente en cada caso, por ejemplo, devolviendo una pgina web
compleja a un navegador y unos pocos datos de aviso a un pequeo
dispositivo IoT
Pgina 9 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Es posible especificar una lista de opciones separadas por comas en lugar de un


nico valor en las cabeceras para indicar que se admiten simultneamente varios
valores distintos. Estos valores pueden tener un orden de prioridad que se expresa
segn un coeficiente de calidad q para cada uno. Los coeficientes de calidad se
separan por un signo de punto y coma (;) y pueden usarse tambin asteriscos (*)
para referirse a cualquier tipo o subtipo.
Accept: text/plain,text/xml,application/json;q=0.8,text/*;q=0.9,application/json

En el ejemplo anterior la prioridad del formato JSON es la mayor (0.9) la del texto
plano y la del texto en formato XML, que cumplen la especificacin text/*, es menor
(0.8) e igual entre ellos. En caso de ser posible el servidor debera reaccionar
codificando la respuesta como JSON.
En el siguiente ejemplo de una peticin POST ms completa se accede a la pgina
/iot/grabar_temperatura del servidor llamado polaridad.es usando la versin 1.1 del
protocolo HTTP. El cliente, llamado Sensoreitor-2000 enva los datos codificados en
formato JSON, espera la respuesta como texto plano en formato UTF-8 usando el
espaol de Espaa sin usar compresin, cosa que, por cierto, no es necesario
indicar. Los datos que se envan al servidor ocupan 65 bytes. Al enviar la respuesta
la conexin entre el cliente y el servidor se cerrar.

1 POST /iot/grabar_temperatura HTTP/1.1


2 Host: polaridad.es
3 Accept: text/plain
4 Accept-Charset: utf-8
5 Accept-Encoding: identity
6 Accept-Language: es-ES
7 Connection: close
8 Content-Length: 65
9 Content-Type: application/jsonrequest
10 User-Agent: Sensoreitor-2000
11
12 {"estancia":"pasillo superior","temperatura":22.5,"consumo":2.25}

En el siguiente artculo se explica cmo configurar la base de datos MySQL para


almacenar la informacin enviada por los objetos IoT

Pgina 10 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Preparar la base de datos MySQL o MariaDB

Configurar el servidor de bases de datos


Una vez instalado el conjunto de servicios LAMP, WAMP, MAMP o XAMPP como
se explicaba en el primer artculo de la serie o simplemente despus de instalar en
la mquina que va a actuar de servidor la suma de aplicaciones que implementan
los servicios correspondientes es necesario ajustar algunos aspectos de la
configuracin del servidor de bases de datos MySQL as como crear las bases de
datos y las tablas que se van a utilizar en el servidor web para almacenar datos de
los dispositivos de Internet de las cosas.
Si se utiliza un servidor pblico seguramente el proveedor habr dispuesto algn
tipo de panel para intermediar entre el usuario y la configuracin real de la base
de datos al objeto de reforzar la seguridad en la operacin. De ser as habr que
remitirse a las instrucciones que este proveedor ofrezca. En el caso de ser un
servidor real o virtual hospedado en las instalaciones de un tercero puede darse
una circunstancia equiparable cuando el proveedor lo administre; si se ha
contratado un servidor no-administrado (por el proveedor, administrado por el
usuario) s ser de aplicacin la informacin que sigue.
Como lo importante es conocer las instrucciones que deben darse al gestor de
bases de datos y se entiende que se est usando como un medio para dar soporte
a los dispositivos para la Internet de las cosas, que sera el objeto del proyecto,
puede ser suficiente utilizar la consola ya que el trabajo sobre el propio servidor de
bases de datos ser ocasional. Si la parte de trabajo de gestin empieza a
aumentar puede que merezca la pena, por ser ms cmodo, utilizar un gestor en el
propio servidor, como el popular phpMyAdmin (desde un navegador web) o
Pgina 11 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

localmente, aunque por supuesto accediendo al servidor de bases de datos, con un


administrador como MySQL Workbench desde el que realizar en un avanzado GUI
las operaciones que se van a explicar y muchas otras que quedan fuera de este
artculo y que merecen toda una serie.

Adems de las operaciones ms o menos automticas que pueden hacerse con


MySQL Workbench sobre el servidor, las bases de datos o las tablas tambin es
posible realizar tareas manualmente escribiendo y ejecutando script completos u
rdenes independientes en SQL. Igual que ocurre con la herramienta MySQL
Workbench, SQL requiere captulo aparte y que ser imprescindible conocer a
Pgina 12 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

fondo cuando la parte del trabajo web IoT que se realiza implique una atencin ms
seria al backend de la que se explica aqu.

En cualquier caso, y desde luego para resolver lo necesario de la configuracin la


base de datos para IoT que se est tratando, se puede utilizar la consola.

Configurar root, el administrador principal de MySQL


Si el servidor de bases de datos est en una mquina propia lo primero que hay
que hacer es configurar los permisos administrador del servicio para poder crear
Pgina 13 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

desde esos privilegios otros usuarios (que a su vez podrn tenerlos) y en su caso
las bases de datos y las tablas en las que almacenar la informacin que el sistema
para Internet de las cosas necesita. Se hace con la orden mysql -u root -p
Es importante atender al proceso de instalacin del conjunto de servicios o del
servidor MySQL, segn sea el proceso seguido, ya que, en muchos casos, el propio
instalador se encargar de realizar este paso y otros y no ser necesario repetirlos
salvo cuando se desee modificar la configuracin.

En la orden mysql -u root p se indica con la opcin u el nombre del usuario (root)
y con la opcin -p (de password) que debe solicitarse la clave al acceder a la
consola MySQL. Para volver a la consola del sistema se puede usar la orden quit
para salir
Antes de abandonar la consola de MySQL, para establecer los privilegios del
usuario root se ha utilizado la ordengrant all privileges on *.* to root@localhost
identified by '1234' with grant option; en la que
se otorgan todos los privilegios grant all privileges
en todas las tablas de todas las bases de datos on *.*
al usuario root usando accediendo desde la mquina que ejecuta el servidor
MySQLto root@localhost
usando como clave 1234 identified by '1234'
con permiso para autorizar a otros usuarios with grant option
Pgina 14 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Para poder administrar la base de datos remotamente se deben otorgar privilegios


al usuario correspondiente desde otras ubicaciones. En el ejemplo anterior se
permita que root accediera desde la mquina en la que se ejecuta el servidor de
bases de datos (localhost) con root@localhost, si se utiliza root@% se permitir el
acceso desde cualquier mquina.

Configurar el acceso remoto a la base de datos


Por razones de seguridad, la configuracin inicial del gestor de bases de datos
MySQL no permite el acceso remoto, para cambiarlo es necesario editar el
documento de configuracin, normalmente my.cnf, que normalmente se encuentra
en la ruta /etc/mysql
El recurso que utiliza el servidor de bases de datos consiste en atender slo a las
peticiones que se hagan desde cierta direccin IP que se expresa como valor del
parmetro bind-address Cuando la direccin es 127.0.0.1 (localhost) slo se
atienden peticiones desde la mquina local, si es 0.0.0.0 se atiende a cualquier
direccin. Para permitir accesos externos lo ms frecuente es indicar la direccin IP
(pblica o privada) de la red desde la que se accede, normalmente algo como bindaddress = 192.168.1.74

Pgina 15 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

En la captura de pantalla anterior puede verse que se ha editado my.cnf con la


configuracin de MySQL usando la orden sudo nano /etc/mysql/my.cnf pero, como se
deca ms arriba, una vez que hay acceso con privilegios administrativos puede
usarse un GUI como MySQL Workbench.

Crear las bases de datos


Una vez configurado el servidor de bases de datos pueden crearse las bases de
datos y las tablas en las que almacenar los datos IoT. Para hacerlo, se pueden usar
rdenes SQL desde la consola o desde el GUI de un gestor.
La orden CREATE DATABASE temperaturas; crea la base de datos temperaturas Para
evitar errores puede usarse la forma CREATE DATABASE IF NOT EXISTS
base_datos_temperaturas;
que
creara
la
base
de
datos
base_datos_temperaturas slo si no existe actualmente.

Crear las tablas


Como en diferentes bases de datos podran existir tablas con igual nombre se
puede hacer referencia a una de ellas precediendo su nombre por el de la base de
datos y separando ambos por un punto, algo como base_datos.tabla Esta notacin
se puede extender tambin al nombre de los campos base.tabla.campo
Si se omite el nombre de la base de datos al operar sobre una tabla (en este caso,
al crearla) se considera que se hace referencia a la ltima seleccionada. Para
seleccionar expresamente una concreta se puede utilizar la orden USE e indicar su
nombre USE base_datos_temperaturas;
Al crear las tablas en las bases de datos, en la misma operacin, se suele aadir la
informacin de los campos que las forman (aunque tambin es posible alterarlas
posteriormente) Igual que se hace con la base de datos, se puede crear la tabla
slo si no existe aadiendo la clusula IF NOT EXISTS o al contrario, asegurarse de
borrar la tabla antes de crearla slo si existe usando DROP TABLE IF EXISTS
valor_temperaturas;

Para permitir nombres de tablas o bases de datos que pudieran entrar en conflicto
con rdenes o procedimientos se puede utilizar el signo de acento grave, llamado a
veces comilla invertida, para rodear el nombre y evitar conflictos o errores en las
rdenes SQL.

Pgina 16 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Definir los campos


Los campos que se aaden al crear la tabla se indican encerrndolos entre
parntesis e indicando el tipo de datos que almacenan. Los tipos de datos que
suelen usarse en una base de datos para almacenar informacin de dispositivos
conectados a la Internet de las cosas son los enteros (INT o BIGINT) decimales
(DECIMAL, DOUBLE o FLOAT) de tiempo (DATE, TIME, DATETIME o TIMESTAMP) y de texto
(principalmente VARCHAR aunque existen otros como TEXT pero no se usan para IoT)
Despus del tipo de datos, y entre parntesis, se aade la longitud del dato y en su
caso el formato o la precisin.
Al aadir AUTO_INCREMENT a la definicin de un campo se indica al gestor de bases de
datos que, si no se indica otra cosa, al crear un nuevo registro debe almacenarse
automticamente el valor del ltimo ms el incremento correspondiente (que
normalmente es 1) Suele incluirse en los campos que se utilizan como ndices
numricos de los registros.
El cdigo NOT NULL indica que un campo de un registro no puede quedar vaco, que
debe almacenar algn valor.
Al usar DEFAULT en la creacin de un campo de una tabla se indica a MySQL un
valor por defecto para el campo siempre que al aadir un nuevo registro o
modificarlo no se indique otro expresamente. Un valor frecuentemente usado por
defecto, en este caso para monitorizar valores de la IoT, es CURRENT_TIMESTAMP que
permite grabar automticamente la hora actual en un campo al crear un nuevo
registro, por lo que un dato queda automticamente identificado en el tiempo.
Para optimizar el rendimiento de la base de datos es conveniente incluir al final de
la definicin de los campos de la tabla uno que se utilice como ndice con la
clusula PRIMARY KEY (ID) siendo ID el campo elegido como ndice.
Al final de la definicin de una tabla se puede indicar el motor de bases de datos
con el que se gestiona como valor del parmetro ENGINE con el formato
ENGINE=InnoDB; siendo InnoDB el motor elegido en este caso.

Crear bases de datos, tablas y configurar campos en una


sesin SQL
En el cdigo del siguiente ejemplo se renen las rdenes, los pasos que habra que
dar, para crear una base de datos con una tabla mnima.

Pgina 17 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

1 CREATE DATABASE `base_datos_temperaturas`;


2
3 CREATE DATABASE IF NOT EXISTS `base_datos_temperaturas`;
4
5 USE `base_datos_temperaturas`;
6
7 DROP TABLE IF EXISTS `calefacciones`;
8
9 CREATE TABLE IF NOT EXISTS `calefacciones`
10 (
11 `identificador` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
12 `estancia` VARCHAR(32) NOT NULL DEFAULT '',
13 `temperatura` FLOAT(4,2),
14 `fecha` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
15 PRIMARY KEY (`identificador`)
16 )
17 ENGINE=InnoDB;

Crear copias de respaldo de las bases de datos


Una vez configurado el servidor y creadas las base de datos y sus tablas estara
todo listo para almacenar la informacin obtenida por los nodos IoT. Aunque el
objetivo de esta serie de artculos no incluye el mantenimiento, hay una cuestin
administrativa crtica que es importante atender, se trata de las copias de
seguridad. Desde la mayora de los gestores, incluyendo phpMyAdmin y MySQL
Workbench, pueden hacerse copias de seguridad y restaurarlas pero es comn
incluirlas en algn script que las automatice (seguramente junto a la configuracin y
muchos otros documentos) para lo que es ms cmodo usar la herramienta
MySQLDump, un cliente que suele ser parte de una instalacin convencional de
MySQL, o alguna alternativa como MySQL Data Dumper que incluye la orden
mydumper para realizar la copia y myloader para restaurarla

MySQLDump
El formato de la orden mysqldump es muy sencillo, slo hay que indicar el nombre de
usuario user, la contrasea password y la base de datos que se desea copiar o --alldatabases para hacer una copia de seguridad de todas las bases de datos como en
el siguiente ejemplo:
mysqldump --opt --user=pelaez --password=1234 --all-databases > copia.sql

El ejemplo anterior genera el documento copia.sql que contiene las rdenes SQL
(es decir, texto) necesarias para reconstruir todas las bases de datos. Al guardarse
Pgina 18 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

en formato texto, la copia ocupa mucho ms de lo imprescindible por lo que suele


tambin comprimirse para ahorrar espacio en el dispositivo en el que se almacene.
La copia de seguridad generada con la orden del ejemplo se podra restaurar si por
un error se perdiera la informacin con la orden de abajo que ejecuta las
operaciones SQL del documento copia.sql
mysql --user=pelaez --password=1234 < copia.sql

MySQL Data Dumper


Si bien con las operaciones anteriores sera suficiente, es muy comn usar MySQL
Data Dumper, ya casi un estndar por su rendimiento aunque no forme parte de las
herramientas base que se incluyen con MySQL
Las siguientes son las opciones de mydumper ms usadas que, lgicamente, deben
escribirse como parte de la misma orden, separadas por espacios, aunque en este
texto se hayan separado en lneas para facilitar la lectura:
--host polaridad.es

polaridad.es es el nombre del servidor de bases de datos


--port 3306 3306 es el nmero del puerto en el que escucha el servidor (por
defecto es el 3306)
--user pelaez pelaez es el nombre del usuario con el que se accede a la base de
datos
--password 1234 1234 es la clave del usuario con el que se accede a la base de
datos
--database temperaturas temperaturas es el nombre de la base de datos que se
respalda
--no-locks no bloquear la base de datos durante la copia (por defecto se bloquea)
--build-empty-files copiar tambin tablas vacas
--compress-input comprimir la entrada
--compress comprimir la salida (la copia de seguridad resultante)
Para restaurar la copia de seguridad obtenida con mydumper se usa myloader que se
usa principalmente con las siguientes opciones, que deben incluirse en las mismas
rdenes separadas por espacios:
--host polaridad.es

polaridad.es es el nombre del servidor de bases de datos


3306 es el nmero del puerto en el que escucha el servidor (por
defecto es el 3306)
--user pelaez pelaez es el nombre del usuario con el que se accede a la base de
datos
--port 3306

Pgina 19 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

--password 1234

1234 es la clave del usuario con el que se accede a la base de

datos
--directory=copia_iot

copia_iot es la carpeta en la que se encuentra la copia

generada con mydumper


--overwrite-tables sobrescribir las tablas aunque ya existan
--verbose 3 3 es grado de informacin del proceso (ms alto, ms mensajes)
-C usar compresin en el flujo de datos
En el prximo y ltimo artculo de esta serie se explica cmo usar el lenguaje de
programacin PHP para almacenar la informacin obtenida por los dispositivos
conectados a la Internet de las cosas en las bases de datos de las que se ha
hablado en este texto.

Pgina 20 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

Acceder a la base de datos desde el lenguaje de


programacin PHP

En este ltimo artculo de la serie sobre el uso de un servidor web para almacenar
los datos de los dispositivos conectados a la Internet de las cosas, se explica como
grabar en una base de datos MySQL la informacin que los nodos IoT envan al
servidor haciendo peticiones HTTP POST. Los lectores de este artculo, de todo el
blog, puede que no estn especialmente familiarizados con la programacin en
ellenguaje PHP pero seguramente s con la programacin de microcontroladores en
los lenguajes C o C++ as que, salvo algunos detalles, como preceder del signo
dlar ($) a las variables, podrn seguir los ejemplos sin necesidad de mayores
explicaciones ya que se han hecho siguiendo un estilo de programacin muy
neutro, no especfico de PHP.

Almacenar informacin en la base de datos


Como se explicaba en el artculo sobre el almacenamiento de datos de la IoT
haciendo peticiones HTTP POST a un servidor web, al final de las cabeceras, el
cuerpo de la peticin POST contiene los datos que se envan al servidor. La forma
ms comn de enviar esa informacin al servidor es en formato de texto plano
porque es ms sencillo analizarla incluso manualmente. Cuando los datos que se
envan al servidor son complejos seguramente ser conveniente estructurarlos
usando, por ejemplo el formato XML o JSON. En el uso habitual de un servidor web
para gestionar la informacin de dispositivos conectados a la Internet de las cosas
no es frecuente necesitar una estructura de datos por lo que lo normal es enviarlos
en texto plano en el formato variable=valor.
Pgina 21 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

En la peticin HTTP POST del siguiente ejemplo se solicita al servidor polaridad.es


el recurso (normalmente una pgina web) /iot/grabar_temperatura y se le envan
tres variables: ne, tp y cr que contienen respectivamente los valores 12, 10.26
y 2.18 Tambin es importante recordar que hay una lnea en blanco para separar
las cabeceras de los datos.
1 POST /iot/grabar_temperatura HTTP/1.1
2 Host: polaridad.es
3
4 ne=12&tp=10.26&cr=2.18

El objetivo final del siguiente cdigo PHP ser enviar al servidor de bases de datos
MySQL la orden SQL:
1 INSERT
2 INTO `calefacciones`
3 (
4
numero_estancia,
5
temperatura,
6
corriente
7 )
8 VALUES
9 (
10
12,
11
10.26,
12
2.18
13 );

Con la que se crear un nuevo registro (INSERT)


en la base de datos calefacciones (INTO calefacciones)
asignando a los campos (numero_estancia,temperatura,corriente)
los valores correspondientes a la peticin HTTP POST VALUES (12, 10.26, 2.18)
La conexin a la base de datos se realiza con la funcin mysqli_connect conforme
al formato: mysqli_connect($servidor,$usuario,$clave,$base_datos) que
devuelve un puntero al objeto-conexin y que usa la variables que definen el
acceso (como usuario, clave) y que han sido previamente asignadas para futuros
hipotticos usos en el script.
Para

detectar

si

la

conexin ha tenido xito se utiliza la funcin


mysqli_connect_errno() que devuelve el nmero de error que se pueda haber
producido o cero (false) si la conexin se ha establecido correctamente. Para avisar
de los errores se responde con el valor cero a la aplicacin que realiza la peticin
HTTP, en este caso el programa que se ejecuta en el C del nodo IoT.
Pgina 22 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

1 $fin_linea=PHP_EOL;
2 $servidor='localhost';
3 $usuario='pelaez';
4 $clave='1234';
5 $base_datos='base_datos_temperaturas';
6 $conexion=mysqli_connect($servidor,$usuario,$clave,$base_datos);
7 if(mysqli_connect_errno())
8 {
9
echo 0; // Devolver el valor 0 para indicar que se ha producido un error
10 }
11 else
12 {
13 $numero_estancia=(int)$_POST['ne'];
14 $temperatura=(float)$_POST['tp'];
15 $corriente=(float)$_POST['cr'];
16 $consulta_sql ='INSERT INTO calefacciones (numero_estancia,temperatura,corriente) ';
17 $consulta_sql.='VALUES ('.$numero_estancia.','.$temperatura.','.$corriente.');';
18 $resultado=mysqli_query($conexion,$consulta_sql);
19 if($resultado) // Si no se ha producido un error al realizar la consulta
20 {
21
echo mysqli_insert_id($conexion); // Devolver el ndice del nuevo registro (>0!)
22 }
23 else
24 {
25
echo 0; // Devolver el valor 0 para indicar que se ha producido un error
26 }
27 mysqli_close($conexion);
28 }
29 echo $fin_linea;

Antes de incorporar al texto que se almacena en $consulta_sql con el que se


compone la orden SQLque se enva al servidor de bases de datos la informacin
que ha llegado en las variables de la peticin POST se pre procesan, como mnimo,
para evitar un ataque por inyeccin de cdigo SQL. En el ejemplo anterior se fuerza
la conversin al tipo de dato correspondiente (int) (entero) o (float) (decimal en
coma flotante) lo que sera suficiente para eliminar posible cdigo malicioso
aadido a los datos de la peticin al servidor web.
Como puede verse, en el lenguaje PHP se utiliza el smbolo del punto (.) para
concatenar los textos que forman la orden SQL o el operador punto y signo igual
(.=) para aadir un texto a la derecha del que ya almacene una variable y se utiliza
la comilla simple () tambin para encerrar constantes de texto, no slo caracteres.
Aunque en este caso pueden utilizarse tambin comillas dobles (), en lenguaje
PHP se utilizan para procesar el contenido, por ejemplo, incluyendo variables
dentro del texto en el formato $texto="Me llamo $nombre"; como alternativa al
Pgina 23 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

formato $texto='Me llamo '.$nombre; permitiendo, adems, incluir comillas de


un tipo en otro sin necesidad de usar signos de escape siempre que se alternen
dobles dentro de simples o simples dentro de dobles como en la asignacin
$texto='esto no hay que "escaparlo" en PHP';.
Para ejecutar la consulta al servidor MySQL se utiliza la funcin mysqli_query con
el formato mysqli_query($conexion,$consulta_sql) que toma como parmetros
el objeto-conexin a la base de datos y el texto con la orden SQL que se ha
compuesto.
La funcin mysqli_query($conexion,$consulta_sql) devuelve un objeto-cursor
que puede usarse para recorrer los datos devueltos en su caso o, como ocurre en
el ejemplo de arriba, para obtener informacin sobre la operacin, concretamente
para conocer el ndice asignado al nuevo registro que la operacin ha creado en la
tabla calefacciones con la funcin mysqli_insert_id($conexion)
El valor devuelto por mysqli_query($conexion,$consulta_sql) puede evaluarse
como falso en una operacin booleana para determinar que se ha producido un
error. En el ejemplo anterior se usa para devolver, al igual que en el caso del error
de conexin, un cero a la aplicacin que hace la peticin POST. De esta forma, el
programa devolver un nmero mayor que cero que representa el ndice del nuevo
registro si la operacin es correcta o un cero si la operacin produce algn error.
Para liberar los recursos que se han asignado a la conexin a la base de datos se
cierra usando la funcin mysqli_close($conexion)

Leer informacin de la base de datos


Salvo en arquitecturas para fog computing la mayora de los nodos IoT se limitan a
enviar al servidor la informacin que captan sus sensores, es decir, el servidor web
slo comunica con ellos para almacenar la informacin por lo que, con el ejemplo
anterior ya se han resuelto buena parte de los casos que se plantearn en esta
aplicacin. El siguiente paso podra ser crear una web que mostrara los datos
monitorizados por los dispositivos conectados a la Internet de las cosas, un trabajo
de frontend que queda fuera de lo que se est tratando en esta serie de tutoriales.
Lo que s puede ocurrir es que un nodo IoT tenga cierta interactividad y se
comporte de forma diferente en funcin de un histrico de datos o prevea la
posibilidad de alterar su comportamiento conforme a una configuracin que le
llegue de un servidor o incluso el nodo sea una pantalla que muestre una grfica
con los datos que se han monitorizado recientemente en comparacin con los
Pgina 24 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

adquiridos en fechas anteriores. Para todas estas situaciones es interesante


tambin poder leer datos del servidor MySQL a travs del servidor web como se
ilustra en el siguiente ejemplo en el que se simula la obtencin de una lista de las
fechas de los estados de alarma determinados por los momentos en los que la
temperatura super los 40C
1 $fin_linea=PHP_EOL; // Fin de lnea. Usar <br> para HTML si se va a mostrar la salida en algn
2 tipo de pantalla o consola no es necesario
3 $servidor='localhost';
4 $usuario='pelaez';
5 $clave='1234';
6 $base_datos='base_datos_temperaturas';
7 $conexion=mysqli_connect($servidor,$usuario,$clave,$base_datos);
8 if(mysqli_connect_errno())
9 {
10 echo 'Error al conectar a la base de datos: ' . mysqli_connect_error();
11 }
12 else
13 {
14 $consulta_sql='SELECT ';
15 $consulta_sql.='estancia, temperatura, DAY(fecha), MONTH(fecha), YEAR(fecha),
16 TIME(fecha) ';
17 $consulta_sql.='FROM valor_temperaturas ';
18 $consulta_sql.='WHERE temperatura>40.0 ';
19 $consulta_sql.='ORDER BY fecha DESC;';
20 $resultado=mysqli_query($conexion,$consulta_sql); // El tercer parmetro de mysqli_query,
21 no usado, es el modo MYSQLI_STORE_RESULT por defecto o MYSQLI_USE_RESULT para
22 grandes cantidades de datos
23 if($resultado) // Si no se ha producido un error al realizar la consulta
24 {
25
$total_resultado=mysqli_num_rows($resultado);
26
if($total_resultado) // Si se ha encontrado algn resultado
27
{
28
echo 'Se han encontrado '.$total_resultado.' estados de alarma:'.$fin_linea;
29
for($numero_resultado=0;$numero_resultado<$total_resultado) // Recorrer los resultados
30
{
31
mysqli_data_seek($resultado,$numero_resultado); // Mover el cursor al registro
32 correspondiente (no tendra por qu ser consecutivo)
33
$registro=mysqli_fetch_row($resultado); // Almacenar en un vector los datos del
34 registro
35
echo 'El '.$registro[2]; // Tercer campo de la consulta (da)
36
echo ' del '.$registro[3]; // Cuarto campo de la consulta (mes)
37
echo ' de '.$registro[4]; // Quinto campo de la consulta (ao)
38
echo ' a las '.$registro[5]; // Sexto campo de la consulta (hora)
39
echo ' en la estancia "'.$registro[0].'"'; // Primer campo de la consulta (estancia)
40
echo ' la temperatura super el mximo de 40C ('.$registro[1].')'; // Segundo campo de
41 la consulta (temperatura)
42
echo $fin_linea;
43
}
Pgina 25 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

44
45

}
else
{
echo 'No se ha encontrado ningn estado de alarma'.$fin_linea;
}
mysqli_free_result($resultado);
}
mysqli_close($conexion);
}

En el ejemplo de arriba, para consultar la base de datos se usa la orden


SQL SELECT conforme al formato bsico SELECT campos FROM tabla WHERE
condicin ORDER BY campo DESC con la nica peculiaridad de aadir al campo
fecha las funciones DAY, MONTH, YEAR y TIME al objeto de obtener de la misma el da,
el nmero del mes el ao y la hora por separado. La condicin impuesta es que la
temperatura sea mayor que 40.0 y se ordena usando el campo fecha de mayor
(ms actual) a menor (ms antiguo) indicndolo con la clusula DESC
Para recorrer los valores devueltos por la consulta desde un bucle for con una
dimensin conocida se utiliza la funcin mysqli_num_rows($resultado) que indica
el nmero de registros que se han encontrado. Con la funcin
mysqli_data_seek($resultado,$numero_resultado) se puede mover el cursor
de los resultados a una posicin concreta expresada por el contador del bucle
for,$numero_resultado, en el ejemplo.
Para almacenar en un vector los campos del registro que apunta el cursor del
resultado se utiliza la funcin mysqli_fetch_row($resultado) que se asigna a la
variable $registro que despus se usar formando una frase con los diferentes
valores accediendo a ellos por sus ndices.
Una vez que se han recorrido todos los valores se liberan los recursos asignados al
resultado de la consulta SQL con la funcin mysqli_free_result($resultado)

Procesar informacin de la base de datos. Comparar valores.


En algunas ocasiones conviene que el procesado de la informacin se centralice en
el servidor incluso aunque fuera posible realizarla en los nodos IoT al estilo fog
computing. En el siguiente ejemplo las razones que se simulan para hacerlo son de
seguridad; el nodo tiene informacin sobre su clave (cerradura) y sobre una
solicitud (llave) pero no sabe si corresponde dar paso a la combinacin de ambas
as que debe consultarlo al servidor que es el que toma la decisin e informa al
Pgina 26 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

nodo respondiendo cero (para indicar una comparacin incorrecta) o uno (para
indicar que la comparacin tuvo xito) segn el resultado de una consulta a su base
de datos.
Con esta excusa se puede ver un ejemplo en el que se reciben datos del dispositivo
conectado a la Internet de las cosas (un cdigo de llave y otro de cerradura), se
devuelve un resultado (uno o cero segn el resultado sea verdadero o falso) y se
realiza un pequeo procesado de la informacin consistente en comparar los
resultados obtenidos al consultar la base de datos con los enviados por el nodo IoT.
1 $fin_linea=PHP_EOL;
2 $servidor='localhost';
3 $usuario='pelaez';
4 $clave='1234';
5 $base_datos='base_datos_puertas';
6 $conexion=mysqli_connect($servidor,$usuario,$clave,$base_datos);
7 if(mysqli_connect_errno())
8 {
9
echo 0; // Devolver el valor 0 para indicar que la comparacin no es vlida o que se ha
10 producido un error (en este caso es un error)
11 }
12 else
13 {
14 $cerradura=hexdec($_POST["c"]);
15 $llave=hexdec($_POST["l"]);
16 $consulta_sql='SELECT llave FROM cerraduras WHERE cerradura='.$cerradura.';';
17 $resultado=mysqli_query($conexion,$consulta_sql);
18 if($resultado) // Si no se ha producido un error al realizar la consulta
19 {
20
$total_resultado=mysqli_num_rows($resultado);
21
if($total_resultado) // Si se ha encontrado algn resultado
22
{
23
$numero_resultado=0;
24
$buscando_cerradura=TRUE;
25
while($buscando_cerradura&&$numero_resultado<$total_resultado)
26
{
27
mysqli_data_seek($resultado,$numero_resultado);
28
$registro=mysqli_fetch_row($resultado);
29
if($registro[0]==$llave)
30
{
31
$buscando_cerradura=FALSE;
32
}
33
else
34
{
35
$numero_resultado++;
36
}
37
}
38
// echo !$buscando_cerradura;
Pgina 27 de 28

Cmo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT)

39
if($buscando_cerradura)
40
{
41
echo 0; // Devolver el valor 0 para indicar que la comparacin no es vlida (o que se ha
42 producido un error; y aquu no es el caso)
43
}
44
else
45
{
46
echo 1; // Devolver el valor 1 para indicar que la comparacin S es vlida
47
}
48
}
49
else
50
{
51
echo 0; // Devolver el valor 0 para indicar que la comparacin no es vlida o que se ha
52 producido un error
53
}
54 }
55 else
56 {
57
echo 0; // Devolver el valor 0 para indicar que la comparacin no es vlida o que se ha
58 producido un error
}
mysqli_close($conexion);
}
echo $fin_linea;

En el ejemplo anterior se utiliza la funcin hexdec para obtener un nmero decimal


desde un texto que representa uno hexadecimal y que es el enviado por el
dispositivo IoT. la ventaja aadida de usar est funcin es evitar, como se explic
antes, un ataque aadiendo cdigo SQL malicioso a los datos de la peticin POST.

Pgina 28 de 28

Das könnte Ihnen auch gefallen