Arduino enviando datos (Parte 1)

Ricardo Vega / 01 junio 2016
⏰ 6 minutos
Hoy vamos a empezar a ver las diferentes formas que tenemos para comunicar nuestro Arduino con el mundo exterior. Como ya dije en la parte 0 de esta serie, existen diferentes métodos (prácticamente infinitos) dependiendo de las características de nuestro sistema y las prestaciones que deseemos adquirir.
Sin embargo, aunque lógicamente no es posible cubrir todas las posibilidades existentes, si que intentaré mostrar diferentes soluciones con sus pros y contras, dando respuesta a diferentes configuraciones que van desde la más simple y "doméstica" hasta opciones mucho más preparadas para cubrir soluciones complejas más propias del entorno coorporativo.
Si lo piensas bien, en este blog, ya hemos visto una forma de llevar a cabo esta tarea en el último post del curso sobre Python. Puedes repasar todas la información relacionada en el propio post o directamente acudir al código disponible en:
De cualquier modo, vamos a hacer un análisis sencillo aquí y ahora. La idea detrás de toda esta serie de post es sencilla:
Tenemos un sensor que toma datos. Esa tarea la realiza muy bien Arduino, tanto en rapidez como en eficiencia, pero tenemos un problema cuando queremos utilizar esa información. Con "utilizar esa información" me puedo referir a muchas cosas (almacenamiento, consumo, publicación, procesado, etc) pero por mantener una cierta base en todos nuestros ejemplos, vamos a realizar una de las tareas más comunes: almacenar esa información obtenida del sensor en una base de datos para después poder recuperarlos por otros servicios (imagina un panel de visualización web).
Por lo tanto, en todos estos ámbitos van a intervenir al menos dos elementos y es que, como hemos dicho, Arduino, por potencia, no puede almacenar una base de datos (por simple que sea) y aceptar peticiones externas a ella. De ahí que ésta tarea se delegue a un elemento externo con mayor capacidad de cómputo (un ordenador, servidor, Raspberry Pi... una vez más dependiendo de las características y pretensiones del sistema).
En el ejemplo del curso de Arduino, creábamos una página web en el propio Arduino que devolvía el estado (medición) del sensor. Cada X tiempo, nuestro programa escrito en Python, accedía a la página web que levantaba el Arduino, obtenía el valor y lo guardaba en una base de datos. A mayores, también creaba un nuevo servicio que permitía leer la información de base de datos y devolverla, admitiendo cierto nivel de filtrado.
Es decir, ambos sistemas actuaban como servidores: el Arduino servía la información del sensor y el elemento que corría el programa Python accedía a esa información (cliente) y la servía al exterior (servidor). Esta arquitectura es bastante rara y su "porqué" se encuentra precisamente en las pretensiones que tenía a la hora de llevarla a cabo: estábamos aprendiendo Python y el núcleo era ese programa Python que hacía diferentes tareas interesantes como lectura y escritura en base de datos, llamadas a servicios web (tanto externos del Yahoo como del Arduino), parseo de datos y publicación de un servidor web.
En el ejemplo que empezamos a plantear hoy, vamos a hacer las cosas de una forma mucho más "normal" y eficiente. Vamos a plantear una arquitectura cliente-servidor donde nuestro Arduino va a recoger la información y la va a enviar cada X tiempo al servidor (escrito en Python) que va a almacenarlo en base de datos y a su vez va a levantar una forma de acceder a esta información desde el exterior. Todas estas tareas,las vamos a llegar a cabo mediante código Python, creando una API RESTful capaz de darnos una forma estandarizada de llevar a cabo esta escritura/lectura de información. A mayores, voy a aprovechar la ocasión para añadir algunas características interesantes como el modelado de datos, el uso de un ORM (veremos después lo que es) y securizar el acceso a la API.
Como ves, a poco que explicamos las cosas, tenemos un post muy largo, por lo que voy a intentar fraccionarlo en pequeñas partes que puedan resultarte más sencillas de leer.
En la parte de hoy, si te parece, vamos a introducir este primer método, hablando de la arquitectura REST para dejar para los dos próximos posts todo lo que tiene que ver con el servidor, Python y Arduino.
## Qué es REST
Cito directamente a Wikipedia:
La Transferencia de Estado Representacional (Representational State Transfer) o REST es un estilo de arquitectura software para sistemas hipermedia distribuidos como la World Wide Web. El término se originó en el año 2000, en una tesis doctoral sobre la web escrita por Roy Fielding, uno de los principales autores de la especificación del protocolo HTTP y ha pasado a ser ampliamente utilizado por la comunidad de desarrollo.
Es decir, REST nos permite crear servicios y aplicaciones que pueden ser usadas por cualquier dispositivo que trabaje con HTTP, de una forma sencilla y rápida. Este modelo de arquitectura se ha popularizado muchos durante los últimos años y prácticamente es un estándar a la hora de trabajar con APIs y aplicaciones WEB.
Existen una serie de reglas que si bien no es obligatorio su cumplimiento, es más que recomendado para poder desarrollar código mantenible y de calidad. Su funcionamiento se basa en los diferentes métodos HTTP, a saber:
- GET: Para consultar y leer recursos
- POST: Para crear recursos
- PUT: Para editar recursos
- DELETE: Para eliminar recursos.
- PATCH: Para editar partes concretas de un recurso.
Es importante que nos acordemos de esto ya que deberemos relacionarlo con las operaciones que realizamos en nuestra API. Por simplicidad, vamos a definir tareas muy básicas:
- Añadir un nuevo valor del sensor (POST).
- Obtener uno o varios valores de la base de datos (GET).
Por otra parte, GET y POST son los métodos más empleados, así que nos sirve de ejemplo.
Aunque profundizaremos más en el siguiente post, vamos a definir nuestra API en
http://URL-SERVIDOR:PORT/api/v1.0/
y vamos a establecer dos puntos de entrada:
http://URL-SERVIDOR:PORT/api/v1.0/temperature
(GET y POST) para añadir y recuperar valores (si recuperamos, nos devolverá por defecto todos los valores al no hacer ningún tipo de filtrado).http://URL-SERVIDOR:PORT/api/v1.0/temperature/<id>
(GET) para recuperar un valor concreto.
Aunque nosotros lo dejaremos ahí, esta forma que vamos a tener de trabajar te permitirá dejar preparado tu código para ir ampliándolo con aquellas características extra que desees, por ejemplo, borrado mediante el método DELETE.
Creo que va a ser un ejemplo bastante completo que además va a ejemplarizar bastante bien cómo podemos desarrollar una API de calidad para trabajar en el mundo IoT.
Así que, la próxima semana entraremos en profundidad en todo aquello relacionado con Python y el elemento servidor.
Hasta entonces, acuédate de compartir este post con tus amigos y seguidores para poder expandir su alcance lo máximo posible.
¡Muchas gracias por estar ahí y hasta la próxima semana!
Subscríbete a mi newsletter
Actualmente estoy llevando a cabo algunos cambios en mi Newsletter y no es posible apuntarse 😞