Obteniendo datos de la pulsera Fitbit mediante Python y mostrando gráficas en Grafana
Que tal? Hoy vamos con un documento que seguro os interesará a todos aquellos que tengáis una pulsera Fitbit, con las que ya sabéis que podemos obtener datos sobre nuestro estilo de vida y tal… bueno, si os apetece explotar dicha info y verla en preciosas gráficas, este es tu documento! Mediante un script en Python obtendremos las medidas que nos interesen y los almacenaremos en una BD MySQL, para luego con Grafana pintar las gráficas que nos interese!
Como supongo habrá muchos fan por aquí de Raspberry Pi y demás fricadas, imaginaros que tenéis un MagicMirror montado, ya sabéis un espejo con monitores detrás y queréis domotizar vuestra casa dándole otro toque adicional y al veros en un espejo conocer vuestro avance, los kilomentros recorridos, pasos andados, calorias quemadas, gráficas de pulsaciones, pisos subidos… bueno… todo lo puedes conseguir siguiendo estos pasos, un día ya os pondré proyectos interesantes que tengo montados en casa 🙂
Lo dicho, qué necesitaremos? Un servidor con Apache y MySQL instalado, crearemos una BD donde almacenaremos lo que nos interese (veremos un par de ejemplos), nos registraremos en la web de fitbit para crear una App y veremos cómo obtener el Access Token que usaremos en un script de python para chupar la info de la nube de Fitbit en un fichero json que guardaremos en local para posteriormente exportarlo a la BD. Tras eso ya está chupado, como seguro que ya tienes Grafana instalado (y si no hecha un vistazo aki), lo que haremos será hacer consultas MySQL a la BD para obtener lo que nos interese ver!
El escenario es muy sencillo, una Raspberry Pi que cada día a las 23:55h ejecuta un script de python que hace lo comentado, almacena los datos de cada día en las tablas de la BD de MySQL y se accederá desde donde tengamos el Grafana instalado, sea en la misma Raspberry Pi, en otra máquina… Como siempre ya os digo, no soy programador ni desarrollador, sólo os muestro la forma de cómo lo he conseguido por si alguno está interesado de hacer cosas chulas! Seguro que hay otros métodos, pero este no es tan complicado!
Lo primero de todo será acceder a la web de https://dev.fitbit.com y crearnos una cuenta si es que no la tenemos, tras ello, accedemos a https://dev.fitbit.com/apps/new y creamos una aplicación nueva siguiendo estos pasos:
- Application Name: Indicamos un nombre descriptivo, en mi caso Python Pi 197
- Description: Escribimos algo que nos asocie esta app al proyecto con el que andamos.
- Application Website: Ponemos una URL, por ejemplo http://www.bujarra.com
- Organization: Nombre de la organización, p. ej: Bujarra
- Organization Website: Indicamos de nuevo la URL, http://www.bujarra.com
- OAuth 2.0 Application Type: Seleccionamos ‘Personal’
- Callback URL: Dejamos http://google.com
- Default Access Type: Confirmamos que queda como ‘Read Only’.
Grabamos la app y sobre sus propiedades ya podremos ver cual es nuestro Client ID y nuestro Client Secret que anotaremos por ahí ya que lo vamos a necesitar.
Accedemos a https://dev.fitbit.com/apps/oauthinteractivetutorial para generar el access token que será lo que necesitemos para validarnos al hacer las consultas desde python. Así que cumplimentamos los datos del apartado 1, donde indicaremos nuestro Client ID, nuestro Client Secret e indicamos que nos redirija a cualquier web, marcamos la información de nuestra salud que queremos dar acceso e importante, debemos indicar el tiempo de caducidad para el token (86400 para 1 dia 604800 para 1 semana 2592000 para 30 dias 31536000 para 1 año), lo normal será poner el valor de 1 año para no tener que renovar el token. Pulsamos en el enlace que nos muestra y lo abrimos en una pestaña nueva, copiamos la URL.
Y en la Parte 2 pegamos la respuesta y verificamos que los datos son correctos, si es así tendremos ya por fín nuestro token!
Así que mismamente si queremos validar que podemos acceder ya a los datos desde nuestra Raspberry podremos ejecutar el siguiente comando para visualizar los datos de la distancia recorrida el último día cada minuto, si todo es correcto lo mostrará en formato json. Ejecutamos:
[sourcecode]curl -H "Authorization: Bearer NUESTRO_TOKEN" https://api.fitbit.com/1/user/-/activities/distance/date/today/1d.json[/sourcecode]
En esta web tenéis más ejemplos para ver más información de otros valores u otros periodos: https://dev.fitbit.com/reference/web-api/activity/#get-daily-activity-summary.
Y si todo es correcto podremos crear un pequeño script que yo le llamaré ‘fitbit_carga_datos.sh‘ que obtendrá los datos del último dia de Fitbit, tanto la distancia recorrida, los pasos dados, los pisos subidos, los latidos del corazón o el tiempo dormido entre otra info. Cada tipo de info la guardaré en un fichero json que dejaré en el directorio de Apache, ya que luego lo necesitaremos. Este sería el script que carga los datos en BD:
[sourcecode]# DISTANCIA
curl -H "Authorization: Bearer eyJhbGxxxxxxLzI2II0" https://api.fitbit.com/1/user/-/activities/distance/date/today/1d.json > /var/www/temp/fitbit_distancia.json
/usr/bin/python /home/pi/fitbit_distancia.py
# PASOS
curl -H "Authorization: Bearer eyJhbGxxxxxxLzI2II0" https://api.fitbit.com/1/user/-/activities/steps/date/today/1d.json > /var/www/html/fitbit_pasos.json
/usr/bin/python /home/pi/fitbit_pasos.py
# PISOS
curl -H "Authorization: Bearer eyJhbGxxxxxxLzI2II0" https://api.fitbit.com/1/user/-/activities/floors/date/today/1d.json > /var/www/html/fitbit_pisos.json
/usr/bin/python /home/pi/fitbit_pisos.py
# CORAZON
curl -H "Authorization: Bearer eyJhbGxxxxxxLzI2II0" https://api.fitbit.com/1/user/-/activities/heart/date/today/1d.json > /var/www/html/fitbit_corazon.json
/usr/bin/python /home/pi/fitbit_corazon.py
# DORMIR
FETXA=`date +"%Y-%m-%d"`
curl -H "Authorization: Bearer eyJhbGxxxxxxLzI2II0" https://api.fitbit.com/1/user/-/sleep/date/$FETXA.json > /var/www/html/fitbit_dormir.json
/usr/bin/python /home/pi/fitbit_dormir.py[/sourcecode]
Como vemos, tendremos que cambiar y poner bien nuestro token, tras descargarse los datos de la web los guarda en el fichero json como dijimos y a posteriori ejecuta un fichero en python que coge cada json y lo inserta en distinta base de datos.
Lo guardamos y lo hacemos ejecutable!
Por tanto, deberemos crear tantos script de python como métricas vayamos a analizar, pero antes de seguir vamos a hacer un alto en el camino y vamos a crear las base de datos y las tablas que necesitemos, que será donde el fichero python importará cada json en la TABLA correspondiente. Podemos hacerlo mediante un gestor de MySQL como es HeidiSQL o directamente desde la shell de linux conectadonos por shell. Creamos una TABLA para cada medida, en mi caso se llaman las tablas: fitbit_distancia, fitbit_pasos, fitbit_dormir… y son muy sencillas, tienen 2 columnas, una llamada ‘kilometros’ (FLOAT) y otra llamada ‘fecha’ (DATE) en el caso de la BD de distancia; en el de fitbit_pasos serán 2 columnas: pasos y fecha, para fitbit_pisos: pisos y fecha… y así el resto, si? Podríamos crear una sola tabla con más columnas también, pero vamos cada uno como quiera. Ejemplo para crear la tabla:
[sourcecode]CREATE TABLE `fitbit_distancia` (
`kilometros` FLOAT NOT NULL,
`fecha` DATE NOT NULL
)
COLLATE=’latin1_swedish_ci’
ENGINE=InnoDB
;[/sourcecode]
Tras definir donde se almacenan los datos, lo que haremos es crear los ficheros python que leerán los fichero JSON con los datos y luego tratarán su contenido buscando el valor que nos interese e insertándolo en la tabla correspondiente, y yo es la manera como lo conseguí, me imagino que lo dicho habrán mejores formas.. Os dejo un ejemplo de uno de los ficheros Python, será el encargado en este caso de leer los kilometros e introducirlos en la BD:
fitbit_distancia.py
[sourcecode]import urllib
import json
import MySQLdb
db = MySQLdb.connect("localhost","root","CONTRASEÑA","NOMBRE_BASE_DATOS")
cursor = db.cursor()
url = ‘http://IP_RASPBERRY/fitbit_distancia.json’
urllib.urlopen(url).read()
response = urllib.urlopen(url).read()
json_obj = json.loads(response)
for product in json_obj["activities-distance"]:
VALOR = product["value"]
FECHA = product["dateTime"]
cursor.execute("""INSERT INTO fitbit_distancia (kilometros,fecha) VALUES (%s,%s) """,(VALOR,FECHA))
db.commit()[/sourcecode]
Así que, el primer script ‘fitbit_carga_datos.sh’ se bajará las estadísticas de la web de Fitbit en un JSON, y cada script de Python leerá dicho JSON y lo meterá en la tabla correspondiente. Para más comodidad, o por si tenéis dudas, os dejo mis scripts en este enlace, sólo tendréis que poner vuestro Token y crear las tablas que necesitéis! Y programamos para que cada día lo ejecute a las 23:59h, así obtendrá todas las métricas del día. En ‘crontab -e’ añadimos:
[sourcecode]59 23 * * * /home/pi/fitbit_carga_datos.sh[/sourcecode]
Ahora lo malo… bien, esto que hace? Obtiene sólo lo de hoy, no? Y qué pasa si no hemos sincronizado? o si la última vez fue hace 4h? Pues sí, perderíamos los datos no sincronizados, así que un rollo, no? Bien esto que os puse arriba es para comprender cómo funciona. Realmente qué hago yo? Pues similar a esto, pero en vez de obtener las metricas de hoy, a Ftibit le pido las métricas de la última semana! Y así, si por ejemplo ayer, o hace 2 días que no tenemos la pulsera sincronizada, no pasa nada, ya que cada noche me bajo las métricas de los últimos 7 días y las machaco en la BD, así cada día, se baja los últimos 7 y problema solucionado. Si?
Así que os dejo aquí los scripts que estoy utilizando, por si lo que te interesa es sincronizar sólo hoy y obtener con más detalle de cada minuto… o por si te interesa únicamente el total de cada día!
Y ya nada, nos quedará hacer nuestros Dashboards como nos gusten! Lo dicho, usaremos un Grafana que ya tengamos. No es más que añadir como fuente de origen MySQL y hacer las consultas que nos interesen. Podremos añadir paneles y añadir los plugins de tipo Graph para hacer las típicas gráficas… o de Singlestat para mostrar valores (resultados de consultas MySQL)… Si os fijáis en este pantallazo, estoy mostrando datos de 2 pulseras, azul soy yo y rosa es la txabala (y hace pocas semanas que la tiene), así que es hacer cada uno lo que le guste, si? La idea final de todo esto será plasmarlo en un espejo mágico que un día os lo enseñare =)
Os dejo algunas consultas de ejemplo que usé en Grafana por si os son de alguna utilidad:
Grafica de pasos:
[sourcecode]SELECT pasos as value, "Pasos Hector" as metric, UNIX_TIMESTAMP(fecha) as time_sec FROM fitbit_pasos WHERE $__timeFilter(fecha) order by fecha asc[/sourcecode]
Gráfica de distancia (km):
[sourcecode]SELECT kilometros as value, "Hector" as metric, UNIX_TIMESTAMP(fecha) as time_sec FROM fitbit_distancia WHERE $__timeFilter(fecha) order by fecha asc[/sourcecode]
Singlestat que muestra los Kilometros que hice esta semana:
[sourcecode]select sum(kilometros) from fitbit_distancia WHERE DATE(fecha) >= CURDATE() – INTERVAL 7 DAY[/sourcecode]
Utilizar Grafana es muy muy muy sencillo, por lo que de verdad, si no lo tienes instalado, hazlo siguiendo estas instrucciones y luego prueba a crear un Dashboard, añades Paneles y los editas (desde su título), verás que tienes muchas opciones y todas ellas muy sencillas de entender, para que te lo personalices a tu gusto totalmente! Ale, tenemos nuestro cuerpo totalmente controlado! Almacenaremos en base de datos todos los pasos que damos, los kilometros que hacemos, los latidos de nuestro corazón, las horas que dormimos, los pisos que subimos… toca explotarlo!
Seguimos otro día con más, ya veréis que cosas más cuquis podemos ir controlando de nuestra vida..