Estadísticas de sistemas de Raspberry Pi

En mi casa tengo una Raspberry Pi como servidor casero, cumple tareas de broker y también la utilizo para descargar algunos archivos cuando no quiero utilizar la pc; como aun no la tengo dentro de un gabinete, me interesa monitorear la temperatura de la Raspberry para asegurarme que no tenga problemas.

La forma mas sencilla que encontré es crear un canal en thingspeak donde enviar los datos para poder verlo desde cualquier parte, en el canal definí tres campos a utilizar, siempre puedo volver y agregar uno mas: temperatura, cpu y idle (este ultimo quizás no es el más útil).

Es posible agregar mas campos si fuera necesario.

Mediante un simple script en Python recolectamos los datos del sistema de la RPI y los enviamos a ThingSpeak.

Para tomar el valor de uso de la CPU del sistema utilizo un programa llamado iostat , se instala en la RPI con:


1
sudo apt-get install iostat

Afortunadamente iostat tiene un parámetro que permite que la salida del comando sea en formato JSON lo cual hace mucho mas sencillo, si en la terminal ejecutamos:


1
iotstat -c -o JSON

Para ejecutar instrucciones del sistema desde Python importamos la libreria subprocess y lo realizamos de la siguiente manera:


1
2
3
4
5
6
import subprocess
import json
import requests

p = subprocess.Popen(['iostat','-c','-o','JSON'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out, err = p.communicate()

Será necesario procesar out para tomar solo los valores que nos interesa:


1
2
3
4
data = json.loads(out)

system = data['sysstat']['hosts'][0]['statistics'][0]['avg-cpu']['system']
idle = data['sysstat']['hosts'][0]['statistics'][0]['avg-cpu']['idle']

Para obtener la temperatura del sistema utilizamos otro comando:


1
vcgencmd measure_temp

De igual forma que para obtener los valores de cpu realizamos


1
2
3
4
p = subprocess.Popen(['vcgencmd', 'measure_temp'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out, err = p.communicate()

temp = out[5:9]

Por ultimo realizamos un request a ThingSpeak con los datos de los campos y nuestro api key para que actualice el canal:


1
2
3
4
apiKey = "XXXXXXXXXXX" #Replace with your own
url = "https://api.thingspeak.com/update?api_key"+apiKey+"&field1="+str(temp)+"&field2="+str(system)+"&field3="+str(idle)
r = requests.get(url)
print r.status_code

En el siguiente link pueden encontrar el programa completo

Si ejecutamos el programa vamos a informar, pero necesitaríamos programarlo para que se realice de forma periódica, para ello creamos un script bash llamado stats.sh:


1
2
#!/bin/bash
python stats1.py

Damos permisos de ejecución al script con chmod +x stats.py y agregamos la tarea a cron utilizando crontab -e y la siguiente linea:


1
*/5 * * * 0-7 /home/pi/stats.sh

Esto va a reportar los datos cada 5 minutos, si queremos alterar la frecuencia simplemente modificamos los valores de cron (dejo un link donde se explica como utilizarlo en detalle).

De esta forma tendremos la estadística del sistema de nuestra RPI en ThingSpeak

Publicar datos a ThingSpeak con MicroPython

En el articulo anterior vimos como leer datos desde un canal publico en ThingSpeak; en esta ocasión nos interesa enviar datos hacia un canal propio.

Desde el punto de vista del hardware, utilizaremos algo muy sencillo: un nodemcu con un sensor analógico de humedad y una pantalla oled.

Como conectar la pantalla oled se cubrió en un video del canal y el sensor de humedad simplemente va conectado al puerto analógico del NodeMCU.

Por supuesto que no calibramos los datos del sensor, solo nos interesa obtener un valor para probar publicar datos.

Luego que hayamos creado el canal en ThingSpeak (basta con registrarnos en el sitio y luego hacer clic en el botón «New Channel» y elegir los campos); ingresamos en el canal y vamos al menu API Keys:

Sobre el borde derecho tendremos un bloque llamado API Request, donde existen varios tipos un request para actualizar el canal (el que utilizaremos), uno para obtener datos del canal, obtener datos de un campo en particular y el estado del canal.

Copiamos la url indicada, sera del siguiente tipo:

https://api.thingspeak.com/update?api_key=4H0IHE2TESPWITGB&field1=0

Crearemos el siguiente programa en MicroPython, que sera el que utilizaremos para actualizar los datos:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from machine import Pin,I2C,ADC
import ssd1306

import json
import network
import urequests
import time
import wlan

wlan.do_connect()

i2c = I2C(-1, Pin(5), Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

adc = ADC(0)

url = "https://api.thingspeak.com/update?api_key=4H0IHE2TESPWITGB&field1=%s"

while True:
    moisure = adc.read()

    oled.fill(0)
    oled.text(str(moisure),0,0)
    oled.show()

    data = url % moisure
    update = urequests.get(data)
    time.sleep(10)

Una vez que hayamos subido el programa al dispositivo y se ejecute, publicara datos cada 10 segundos en ThingSpeak, luego de un breve periodo de tiempo podremos ver un grafico como este: