Enviando dados da Dragonboard 410c para a nuvem (dweet.io)

Dragonboard dweet

Neste tutorial veremos como enviar dados coletados de alguns periféricos da Dragonboard 410c da Qualcomm para o serviço de nuvem dweet.io. Utilizaremos uma aplicação desenvolvida em python que será responsável por coletar os dados, conectar-se e enviá-los ao dweet.io utilizando o simples método HTTP GET.

 

A proposta é coletarmos dados de frequência da CPU, endereço IP local, redes wifi e dispositivos bluetooth próximos e enviarmos para a nuvem.

 

Antes de começar você precisa ter a imagem Debian gravada na Dragonboard de acordo com o descrito neste outro tutorial.

 

 

Preparação

 

É necessário que você tenha acesso ao console serial da placa através de uma cabo conversor USB serial nível 1.8V. Você encontra mais detalhes sobre essa conexão física aqui e aqui.

 

Após o cabo USB serial conectado à placa e com ela energizada abra uma seção atráves do terminal do seu Host Linux.

sudo screen /dev/ttyUSB0 115200

 

Se necessário, use o comando "dmesg" em seu Host para identificar qual o nome do arquivo de dispositivo que foi dado ao conversor USB serial pelo sistema.

 

Se você estiver utilizando o Windows, você pode abrir a seção com a porta COM através do PuTTY.

 

 

Conexão com a Internet

 

Se você pretende conectar a placa à internet via Wifi, siga os passos a seguir. Caso contrário você poderá usar um adaptador USB Ethernet e ela irá se conectar automaticamente à sua rede local.

 

Após energizar a Dragonboard, e com a conexão serial aberta, o login do root é feito automaticamente, não precisando entrar com nenhuma senha. Vamos agora configurar a conexão wireless através dos seguintes comandos na placa:

echo -e -n "[Match]\nName=wlan0\n\n[Network]\nDHCP=yes\n" > /etc/systemd/network/99-wireless-dhcp.network
echo -e -n "ctrl_interface=/run/wpa_supplicant\nupdate_config=1\n" > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
wpa_passphrase SSID PASSWORD >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
sed -i '/ExecStart=/c\ExecStart=/sbin/wpa_supplicant -u -c/etc/wpa_supplicant/wpa_supplicant-wlan0.conf -Dnl80211 -iwlan0' /lib/systemd/system/wpa_supplicant.service
rm /etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

 

Atente-se ao comando "wpa_passphrase SSID PASSWORD". Você deverá substituir o SSID pelo nome de sua rede wifi e PASSWORD para sua respectiva senha.

 

Agora vamos reiniciá-la com o comando:

reboot

 

Se optar por acessar a placa via ssh, utilize o usuário linaro e senha linaro.

 

 

Instalação de pacotes adicionais

 

Após reiniciada e com o devido acesso à internet, vamos instalar os pacotes adicionais atráves dos seguintes comandos na Dragonboard:

apt-get update
apt-get -y install python-dev python-setuptools python-pip libbluetooth-dev
pip install wheel
pip install wpa_supplicant requests pybluez

 

 

Rodando a aplicação

 

Para coletar os dados de frequência da CPU (em Hz), endereço IP local, redes wifi (SSID, dBm e qualidade do sinal), dispositivos bluetooth (nome e endereço MAC) próximos e posterior envio ao dweet foi desenvolvida a seguinte aplicação:

https://gist.github.com/diegosueiro/2c52114e7cb253988e70890b621382f3

#!/usr/bin/env python

from wpa_supplicant.core import WpaSupplicantDriver
from twisted.internet.selectreactor import SelectReactor
import threading
import time
import sys
import requests
import subprocess
import bluetooth
import socket
import getopt
import os

dweet_url = "https://dweet.io:443/dweet/for/"


def send_data(thingname, data):
    rqsString = dweet_url+thingname+'?'+str(data)
    print rqsString
    try:
        rqs = requests.get(rqsString, timeout=10)
        print rqs.status_code
    except requests.exceptions.RequestException as e:
        print e
    except KeyboardInterrupt:
        raise


def usage():
    print "Execute me with sudo and with the following parameters"
    print "-h,--help"
    print "-t,--thingname=some_fancy_name -> url with data at: \
            http://dweet.io/follow/some_fancy_name  (mandatory)"
    print "-w,--wirelesscount -> number of wireless network data \
            to send (optional, default=1)"
    print "-b,--btcount -> number of bluetooth devices data to send \
            (optional, default=1)"
    print "-i,--interval -> interval to send data in seconds \
            (optional, default=10)"


def main():
    if os.getuid() != 0:
        usage()
        sys.exit(2)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "ht:w:b:i:",
                                   ["help", "thingname=", "wirelesscount=",
                                   "btcount=", "interval="])
    except getopt.GetoptError as e:
        print str(e)
        usage()
        sys.exit(2)

    thingname = None
    wirelesscount = 1
    btcount = 1
    interval = 10

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-t", "--thingname"):
            thingname = a
        elif o in ("-w", "--wirelesscount"):
            wirelesscount = a
        elif o in ("-b", "--btcount"):
            btcount = a
        elif o in ("-i", "--interval"):
            interval = int(a)
        else:
            print "Invalid parameter"
            usage()
            sys.exit(2)

    if thingname is None:
        print "You missed the --thingname= paramenter"
        usage()
        sys.exit(2)

    print "Program Parameters: --thingname=%s --wirelesscount=%s \
    --btcount=%s --interval=%s" % (thingname, wirelesscount, btcount, interval)

    # Wireless Initialization #

    # Start a simple Twisted SelectReactor
    reactor = SelectReactor()
    threading.Thread(target=reactor.run,
                     kwargs={'installSignalHandlers': 0}).start()
    time.sleep(0.1)  # let reactor start

    # Start Driver
    driver = WpaSupplicantDriver(reactor)

    # Connect to the supplicant, which returns the "root"
    # D-Bus object for wpa_supplicant
    supplicant = driver.connect()

    # Get an interface w/ the supplicant
    interface = supplicant.get_interface('wlan0')

    while True:
        try:
            time.sleep(interval)
            # Get Board Local IP Addr
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(("8.8.8.8", 80))
            localip = s.getsockname()[0]
            s.close()
            print "Sending Local IP Data: "+localip

            # Get Board CPU Frequency
            cpuinfo_cur_freq = "cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq"
            cpufreq = subprocess.check_output(cpuinfo_cur_freq, shell=True)
            print "Sending CPU Freq Data: "+cpufreq

            send_data(thingname, 'localip='+str(localip)+'&'+'cpufreq='+str(cpufreq))

            print "Issue wireless scan"
            scan_results = interface.scan(block=True)
            print ("Found %d wireless networks" % len(scan_results))
            for idx, bss in enumerate(scan_results[:int(wirelesscount)]):
                ssid = bss.get_ssid()
                dBm = bss.get_signal_dbm()
                sigQA = bss.get_signal_quality()
                print "Sending Wireless Data: SSID=%s dBm=%s sigQA=%s" % (ssid, dBm, sigQA)
                send_data(thingname, 'ssid'+str(idx)+'='+str(ssid)+
                          '&'+'dBm'+str(idx)+'='+str(dBm)+
                          '&'+'sigQA'+str(idx)+'='+str(sigQA))

            print "Issue bluetooth scan"
            nearby_devices = bluetooth.discover_devices(duration=8,
                                                        lookup_names=True,
                                                        flush_cache=True,
                                                        lookup_class=False)
            print "Found %d Bluetooth devices" % len(nearby_devices)
            for idx, (addr, name) in enumerate(nearby_devices[:int(btcount)]):
                print("Sending Bluetooth Data: btname=%s btaddr=%s" % (name, addr))
                send_data(thingname, 'btname'+str(idx)+'='+str(name)+
                          '&'+'btaddr'+str(idx)+'='+str(addr))

        except (Exception, KeyboardInterrupt) as e:
            print str(e)
            print "Bye"
            reactor.callFromThread(reactor.stop)
            time.sleep(1)
            if reactor.running:
                reactor.stop()
            sys.exit()


if __name__ == "__main__":
    main()

 

O programa aceita os seguintes parâmetros:

  • -h,--help
  • -t,--thingname=some_fancy_name -> url at: http://dweet.io/follow/some_fancy_name (mandatory)
  • -w,--wirelesscount -> number of wireless network data to send (optional, default=1)
  • -b,--btcount -> number of bluetooth devices data to send (optional, default=1)
  • -i,--interval -> interval to send data in seconds (optional, default=10)

 

Faça do download da aplicação com os seguintes comandos:

wget https://gist.githubusercontent.com/diegosueiro/2c52114e7cb253988e70890b621382f3/raw/22f5d6b3e7c0179cb3d4ed9961747daed1ac1909/dragonboard-to-dweet.py
chmod +x dragonboard-to-dweet.py 

 

E execute-a da seguinte maneira:

./dragonboard-to-dweet.py -t my-thing-fancy-name

 

Certifique-se de escolher um nome diferente para "my-thing-fancy-name".

 

Após iniciada a aplicação abra a seguinte URL em seu browser:

http://dweet.io/follow/my-thing-fancy-name

 

Na figura 1 podemos ver um exemplo da página com os dados enviados periodicamente:

 

Dragonboard dweet - Dados enviados pela Dragonboard no dweet.io
Figura 1 - Dados enviados pela Dragonboard no dweet.io

 

Você pode variar os outros parâmetros citados acima para enviar mais informações, bem como modificar a frequência de envio dos dados.

 

Se desejar criar um dashboard mais aprimorado você pode usar o freeboard.io e integrar com os dados recebidos pelo dweet como o exemplo da figura 2:

 

Integração entre dweet e freedboard para visualização dos dados enviados pela Dragonboard
Figura 2 - Integração entre dweet e freedboard para visualização dos dados enviados pela Dragonboard.
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Diego Sueiro
Formado em Engenharia de Controle e Automação pela UNIFEI e CEO do Embarcados, atualmente trabalho na Inglaterra com Desenvolvimento de Sistemas Linux Embarcado Real Time. Sou consultor e desenvolvedor de software para Sistemas Embarcados com vasta experiência em projetos com processadores de 8bits a 32bits, sistemas bare metal, RTOS, Linux Embarcado e Android Embarcado. Um apaixonado por Pink Floyd e Empreendedorismo.

2
Deixe um comentário

avatar
 
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Diego SueiroAnderson Ignacio da Silva Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Anderson Ignacio da Silva
Visitante
Ânderson Ignacio da Silva

Excelente artigo Diego, parabéns! Uma dúvida que tenho é se poderia utilizar o mesmo script ou equivalente para outras SBC's que possuíssem os mesmo pacotes como wpa_supplicant e tal?

Diego Sueiro
Visitante
Diego Sueiro

Olá Anderson,

Com toda a certeza.