Configurar el Wi-Fi de Raspberry Pi a través de Bluetooth para luego enviar datos a Ubidots.

Al menos una vez en tu vida te ha costado configurar las credenciales Wi-Fi de una Raspberry Pi sólo porque no tenías un monitor contigo en ese momento.

En esta guía, voy a describir cómo configurar un Raspberry Pi con un AP (Access Point) que puede a través de una aplicación android portátil. ¿No puedes conectar un cable Ethernet sólo porque estás en una nueva ubicación? ¡No se preocupe - Después de seguir esta guía, usted será capaz de utilizar su Pi en cualquier lugar, todo lo que necesita es escanear la red, elegir la red deseada para establecer la conexión con, escribir las credenciales, y ya está conectado!

He desplegado una sencilla herramienta que permite configurar el SSID y el PSK de la comunicación Wi-Fi sobre Bluetooth de la Raspberry pi. Por el momento, es super básico - sólo necesitas haber emparejado previamente tu teléfono Android con tu Raspberry Pi y he escrito una aplicación básica para Android.

Personalmente, creo que esto es realmente útil para aquellos que andan por ahí con su Raspberry Pi, moviéndola de un taller a otro, llevándola de casa a la escuela, además de todos los casos posibles que tengas en mente ahora mismo... Ahora, sin discutir más, vamos a empezar a construir cosas chulas, empezando por la instalación del script python que se va a ejecutar en nuestra Raspberry Pi.

Requisitos

Paso a paso

  1. Configuración del Bluetooth de Raspberry Pi
  2. Emparejar Raspberry Pi y teléfono Android
  3. Ajuste del sensor DHT22 - Hardware
  4. Configuración del sensor DHT22 - Software
  5. Envío/Visualización de datos a Ubidots

1. Configuración del Bluetooth de Raspberry Pi

Al principio, necesitarás un monitor + teclado conectados, acceso alternativo a la Raspberry Pi a través de SSH sólo para poder establecer todas las configuraciones necesarias a través de la Terminal de Raspbian.

Ejecute los siguientes comandos con cuidado para establecer las configuraciones adecuadas:

  1. Instala bluez (librería bluetooth de Python):
$ sudo apt-get install python-bluez

2. Inicie el demonio Bluetooth en modo de compatibilidad. Para ello, edita /etc/systemd/system/dbus-org.bluez.service, ejecutando el siguiente comando:

$ sudo nano /etc/systemd/system/dbus-org.bluez.service

3. A continuación, modifique el parámetro ExecStart:

ExecStart=/usr/lib/bluetooth/bluetoothd -C

4. Ahora, cargue el perfil del puerto serie utilizando el siguiente comando:

$ sudo sdptool add SP

5. Para guardar los cambios correctamente, reinicie su Pi:

$ sudo reboot

Después del reinicio vamos a emparejar el Bluetooth con nuestro teléfono android

2. Emparejamiento de Raspberry Pi y teléfono Android.

1. Empareja tu teléfono Android con tu Raspberry Pi. Para ello, enciende el bluetooth de tu teléfono y ejecuta el siguiente comando en tu Pi:

$ bluetoothctl

A continuación, una vez iniciado el proceso de emparejamiento, introduzca los siguientes parámetros. (Consulte la imagen para tener una mejor idea del proceso de flujo)

encendido
descubrible encendido
escanear activado

En este punto, tu teléfono aparecerá en la lista de dispositivos disponibles. Toma nota de la dirección de tu teléfono.

trust <PHONE_ADDRESS>
pair <PHONE_ADDRESS>

2. Para salir del bluetooth ctl, escribe el comando quit:

$ quit

3. [OPCIONAL - PRO TIP] Puedes saltarte la configuración anterior, configurando el Bluetooth con la UI de Raspbian. Sólo tiene que pulsar el icono de Bluetooth, y seleccione el Bluetooth de su teléfono.

4. Después de emparejar el Bluetooth, añade el script python directamente en el Raspbian escribiendo el comando nano y copia/pega el código fuente, o puedes copiar directamente el archivo run.py.

$ sudo nano run.py

Código fuente (copiar/pegar):

#!/usr/bin/env python
#Run.py
import os
from bluetooth import *
from wifi import Cell, Scheme
import subprocess
import time
wpa_supplicant_conf = "/etc/wpa_supplicant/wpa_supplicant.conf"
sudo_mode = "sudo "
def wifi_connect(ssid, psk):
    # write wifi config to file
    cmd = 'wpa_passphrase {ssid} {psk} | sudo tee -a {conf} > /dev/null'.format(
            ssid=str(ssid).replace('!', '\!'),
            psk=str(psk).replace('!', '\!'),
            conf=wpa_supplicant_conf
        )
    cmd_result = ""
    cmd_result = os.system(cmd)
    print cmd + " - " + str(cmd_result)
    # reconfigure wifi
    cmd = sudo_mode + 'wpa_cli -i wlan0 reconfigure'
    cmd_result = os.system(cmd)
    print cmd + " - " + str(cmd_result)
    time.sleep(10)
    cmd = 'iwconfig wlan0'
    cmd_result = os.system(cmd)
    print cmd + " - " + str(cmd_result)
    cmd = 'ifconfig wlan0'
    cmd_result = os.system(cmd)
    print cmd + " - " + str(cmd_result)
    p = subprocess.Popen(['hostname', '-I'], stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    out, err = p.communicate()
    if out:
        ip_address = out
    else:
        ip_address = "<Not Set>"
    return ip_address
def ssid_discovered():
    Cells = Cell.all('wlan0')
    wifi_info = 'Found ssid : \n'
    for current in range(len(Cells)):
        wifi_info +=  Cells[current].ssid + "\n"
    wifi_info+="!"
    print wifi_info
    return wifi_info
def handle_client(client_sock) :
    # get ssid
    client_sock.send(ssid_discovered())
    print "Waiting for SSID..."
    ssid = client_sock.recv(1024)
    if ssid == '' :
        return
    print "ssid received"
    print ssid
    # get psk
    client_sock.send("waiting-psk!")
    print "Waiting for PSK..."
    psk = client_sock.recv(1024)
    if psk == '' :
        return
    print "psk received"
    print psk
    ip_address = wifi_connect(ssid, psk)
    print "ip address: " + ip_address
    client_sock.send("ip-address:" + ip_address + "!")
    return
try:
    while True:
        server_sock=BluetoothSocket( RFCOMM )
        server_sock.bind(("",PORT_ANY))
        server_sock.listen(1)
        port = server_sock.getsockname()[1]
        uuid = "815425a5-bfac-47bf-9321-c5ff980b5e11"
        advertise_service( server_sock, "RPi Wifi config",
                           service_id = uuid,
                           service_classes = [ uuid, SERIAL_PORT_CLASS ],
                           profiles = [ SERIAL_PORT_PROFILE ])
        print "Waiting for connection on RFCOMM channel %d" % port
        client_sock, client_info = server_sock.accept()
        print "Accepted connection from ", client_info
        handle_client(client_sock)
        client_sock.close()
        server_sock.close()
        # finished config
        print 'Finished configuration\n'
except (KeyboardInterrupt, SystemExit):
    print '\nExiting\n'

5. Tras el paso anterior, es hora de hacer ejecutable el script dándole los permisos necesarios:

$ chmod +x run.py

A correr:

$ sudo ./run.py

6. En este punto, abre la aplicación android y selecciona la raspberrypi en los dispositivos Bluetooth emparejados. Introduce el SSID, PSK y pulsa el botón Start Configuration. En pocos segundos el Wi-Fi de la Raspberry Pi debería estar conectado, como se muestra en las imágenes de abajo.

7. Para ejecutar el script durante el proceso de arranque de la pi, edita /etc/rc.local y añade la siguiente línea de código:

(sleep 10;/ruta/a/script/./ejecutar.py)&

3. Configuración del sensor DHT22 - Hardware

1. Establezca las conexiones adecuadas, como se muestra en el diagrama siguiente:

4. Configuración del sensor DHT22 - Software

1. Instale los paquetes necesarios ejecutando los siguientes comandos:

$ sudo apt-get update
$ sudo apt-get install build-essential python-dev python-openssl git

2. Carga la librería de sensores. En mi caso, utilizo una librería pre-construida de Adafruit que soporta una gran variedad de sensores:

$ git clone https://github.com/adafruit/Adafruit_Python_DHT.git && cd Adafruit_Python_DHT

3. Con la librería ya cargada, ejecuta el siguiente comando para crear una librería Python que te permita hacer la integración fácilmente para este y otros proyectos.

$sudo python setup.py install

4. Si todo funciona correctamente, deberíamos poder leer la temperatura y la humedad. La forma más fácil es utilizar primero los archivos de demostración ya disponibles en nuestra Pi:

$ cd ejemplos

5. Ejecuta el siguiente código de ejemplo. Donde el primer parámetro (11) indica qué sensor se utilizó (22 para el DHT22) y el segundo, a qué GPIO está conectado (no el número de pin, sino el número de GPIO). Esto produce una salida como la siguiente:

$ sudo ./AdafruitDHT.py 11 4

Resultado esperado:

$ sudo ./AdafruitDHT.py 11 4

Temp=24.0* Humedad=41.0%

5. Envío de datos a Ubidots

1. Crea un script python utilizando el editor nano, y pega el código que aparece a continuación en el terminal. Para ello, inserte el siguiente comando:

$ sudo nano ubidots3.py

Código fuente:

import time
import requests
import math
import random
import sys
import Adafruit_DHT
sensor = 22 #Select your DHT version 
pin = 18 #Enter your Pin of DHT22
TOKEN = "…"  # Put your TOKEN here
DEVICE_LABEL = "Raspberrypi"  # Put your device label here 
VARIABLE_LABEL_1 = "temperature"  # Put your first variable label here
VARIABLE_LABEL_2 = "humidity"  # Put your second variable label here
# Try to grab a sensor reading.  Use the read_retry method which will retry up
# to 15 times to get a sensor reading (waiting 2 seconds between each retry).
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
# Un-comment the line below to convert the temperature to Fahrenheit.
# temperature = temperature * 9/5.0 + 32
# Note that sometimes you won't get a reading and
# the results will be null (because Linux can't
# guarantee the timing of calls to read the sensor).
# If this happens try again!
def build_payload(variable_1, variable_2):
	    # Creates two random values for sending data
	value_1 = temperature
	value_2 = humidity
	payload = {variable_1: value_1,
               variable_2: value_2,
               }
	return payload
def post_request(payload):
    # Creates the headers for the HTTP requests
    url = "http://industrial.api.ubidots.com"
    url = "{}/api/v1.6/devices/{}".format(url, DEVICE_LABEL)
    headers = {"X-Auth-Token": TOKEN, "Content-Type": "application/json"}
    # Makes the HTTP requests
    status = 400
    attempts = 0
    while status >= 400 and attempts <= 5:
        req = requests.post(url=url, headers=headers, json=payload)
        status = req.status_code
        attempts += 1
        time.sleep(1)
    # Processes results
    if status >= 400:
        print("[ERROR] Could not send data after 5 attempts, please check \
            your token credentials and internet connection")
        return False
    print("[INFO] request made properly, your device is updated")
    return True
def main():
    payload = build_payload(
    VARIABLE_LABEL_1, VARIABLE_LABEL_2)
    print("[INFO] Attemping to send data")
    post_request(payload)
    print("[INFO] finished")
if __name__ == '__main__':
    while (True):
		print('Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity))
		humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
		main()
    time.sleep(1)
    ```

Después de pegar el código fuente, tienes que asignar el Ubidots TOKEN donde se indica en el script python:

$ sudo nano ubidots3.py

2. Ahora, con todo configurado, puede ejecutar el código de ejemplo para empezar a transmitir datos a su cuenta de Ubidots:

$ sudo python ubidots3.py

En este punto, si te diriges a la sección de dispositivos de tu cuenta de Ubidots podrás ver un nuevo dispositivo creado llamado "RaspberryPi".

3. Para visualizar tus datos de forma eficiente, vamos a crear un Ubidots' Dashboard. Para crearlo, ve a la sección Dashboard (Datos > Dashboard)

4. A continuación, pulsa en "Añadir nuevo widget", y selecciona tu widget:

5. Seleccione la variable que desea visualizar:

6. Dale un nombre personalizado al widget y pulsa el icono verde para finalizar la creación del widget.

Ahora puede supervisar variables de forma remota desde cualquier lugar gracias a la plataforma de desarrollo de aplicaciones IoT de Ubidots:

Artículos recomendados: