A Internet das Coisas (IoT, na sigla em inglês) é onda do momento no mundo Maker. E colocar nossas “coisas” na rede está ficando cada vez mais fácil. Neste artigo, vou ensinar como utilizar o Bottle para colocar a Raspbery Pi como um servidorzinho web e servir dados a outros dispositivos através da rede, ou mesmo, controlá-la via web.

O pacote Bottle
O Bottle[1] é uma micro framework web para Python. O projeto é open-source, e seu código-fonte, sob licensa MIT, está disponível no Github[2].

Uma das coisas mais legais que eu achei do Bottle, é que ele é distribuído em um único arquivo .py, e a única dependência é a Python Standard Library.

HelloBottle
Para nos familizarmos com a framework, nada melhor que o bom e velho HelloWorld (a.k.a HelloBottle). Mas antes de mais nada, vamos criar um diretório de trabalho e baixar o bottle:

$ mkdir hello_bottle
$ cd hello_bottle
$ wget https://github.com/bottlepy/bottle/raw/master/bottle.py

Através do download direto, baixamos a versão mais recente do bottle, com o ônus de ela poder ser um pouco instável. Se você se preocupa com isso, instale-o através do pip ou do easy_install.

Ótimo, com o pacote em mão podemos podemos prosseguimos para o código:

from bottle import run, route

@route('/hello')
def test_bottle():
	return 'Olá mundo!'

run(host='0.0.0.0', port=8080)

Na primeira linha,

from bottle import run, route

do pacote bottle, importamos as funções run e route.

No trecho,

@route('/hello')
def test_bottle():
	return 'Olá mundo!'

Definimos que ao chamarmos o http://<endereço_da_rpi>/hello executaremos a função test_bottle. O client receberá a string retornada da função, que nada mais é que uma página html.

A função run(),

run(host='0.0.0.0', port=8080)

é responsável por rodar o nosso servidorzinho. O parâmetro “host” indica qual o endereço que o servidor escutar. Passando 0.0.0.0 indicamos que qualquer endereço pode acessar nosso servidor. Se você pusesse 127.0.0.1, você só conseguiria acessar o servidor a partir da própria Raspberry, o que é interessante somente para testes. Já o parâmetro “port”, define qual porta o servidor escuta, no caso, a porta 8080.

Para rodar o nosso teste, salve o arquivo hello_bottle.py com o código acima, e digite no terminal:

$ python hello_bottle.py

em outra instância do terminal, descubra o endereço ip da sua Raspberry, digitando:

ifconfig eth0

Abra um browser em outro computador na mesma rede e digite na barra de endereços, substituindo 10.0.0.110 pelo endereço da sua Raspberry:

http://10.0.0.110:8080/hello

No browser , você deve ler Olá Mundo!.

Conversando com o servidor: Pegando a temperatura da CPU
A idéia não é ficar retornando páginas html, mas sim dados que possam ser manipulados por outros servidores, páginas dinâmicas ou por um app em um celular. Para isso, quando requisitado, ao invés de retornar uma string com um código html, vamos retornar dados no formato JSON[3]. Nesse formato, os dados são melhor manipuláveis e podem ser integrados a páginas dinâmicas(AJAX) e tudo mais.

No próximo exemplo, vamos ler a temperatura da CPU da Raspberry, e retornar em formato JSON para que possa ser lida por outras aplicações.

from bottle import route, run, response
import json

@route('/temperature')
def getTemperature():
        file = open('/sys/class/thermal/thermal_zone0/temp')
        cpu_temp = int(file.read())/1000.0
        file.close()

        response.content_type = 'application/json'
        cpu_temp_json = json.dumps({"temperature":str(cpu_temp)})

        return cpu_temp_json

if __name__ == '__main__':
        run(host='0.0.0.0', port=8080)

No código acima, percebemos uma mudança, em relação ao “hello world” do código anterior, já nas duas primeiras linhas:

from bottle import route, run, response
import json

veja que importamos mais dois objetos: response do pacote bottle e o json, que é nativo.

Em seguida, definimos a função getTemperature():

@route('/temperature')
def getTemperature():
        file = open('/sys/class/thermal/thermal_zone0/temp')
        cpu_temp = int(file.read())/1000.0
        file.close()

        response.content_type = 'application/json';
        cpu_temp_json = json.dumps({"temperature":str(cpu_temp)})

        return cpu_temp_json

Primeiro, abrimos o arquivo temp, localizado em /sys/class/thermal/thermal_zone0/, para leitura. Na linha seguinte, dividimos o valor lido por 1000, e o resultado será o valor da temperatura da cpu em grau Celsius.

As três linhas seguintes determinam o tipo de resposta que o servidor entregará ao cliente:

response.content_type = 'application/json'
cpu_temp_json = json.dumps({"temperature":str(cpu_temp)})

return cpu_temp_json

Primeiro, setamos o tipo de resposta para “application/json” através do response.content_type. Segundo, gravamos na variável cpu_temp_json, o resultado da serialização da temperatura com uma chave(json key) chamada “temperature”. Em seguida, retornamos cpu_temp_json. Assim, quando fizermos a requisição através do endereço http://10.0.0.110:8080/temperature, a resposta será do tipo JSON.

json

E agora?

Bueno, a partir daqui você já pode sair controlando a sua Raspberry Pi através de sua rede local. Com um pouco de configuração em seu roteador será possível controla-lá não só na rede local, mas através da internet também. Vale a pena dar uma pesquisada.

Que tal controlar o I/O, ler um sensor, ou mesmo rebootar sua Rasp pela rede? Legal, né?Mas isso é assunto para outros posts… Até lá! 🙂

Referências:
[1] http://bottlepy.org/docs/dev/index.html
[2] https://github.com/bottlepy/bottle
[3] http://json.org/

Anúncios