Aula 15: Previsão do tempo

Agora que vimos como funciona o display OLED, podemos realizar projetos um pouco mais complexos utilizando esse componente. Nesta aula iremos vamos apresentar no display OLED a previsão do tempo, aí você sempre vai saber se precisa realmente levar um casaco.

Foto do projeto

Para desenvolver o projeto desta aula, vamos aprender um pouco como funciona o GitHub (caso você não conheça) e veremos como fazemos requisições.

GitHub

O Git é um sistema de controle de versão muito utilizado em diversos projetos de desenvolvimento de software, como o desenvolvimento do Linux, por exemplo. É tão utilizado que já vem instalado no Raspbian e muitos outros sistemas operacionais.

Logo do GitHub

O GitHub é um plataforma que mais hospeda projetos que utilizam Git. Nela, diversos desenvolvedores e usuários compartilham programas, bibliotecas e APIs. Para o nosso projeto vamos copiar uma pasta do GitHub e utilizar alguns arquivos dela. Essa pasta é do Maker Hero (colaborador do nosso blog) DQ e foi criada para o post que foi base para este projeto.

Primeiro passo é copiar a pasta para a sua Raspberry Pi, utilizando o seguinte comando:

git clone https://github.com/dquadros/Clima

Com isso, será criada uma pasta chamada “Clima” dentro da pasta do usuário.  É isso que o comando “clone” faz, copia a pasta baixando de um link no GitHub ou de outra pasta local. Muitas vezes para instalar bibliotecas precisamos clonar a pasta de um repositório e executar um programa dentro dela.

Como serão utilizados as imagens dessa pasta, ou você cria o programa na pasta “Clima” ou mover os arquivos para a pasta do usuário. Minha sugestão é escolher a segunda opção, como você pode estar trabalhando somente com o terminal (ou mesmo acessando via SSH) você precisa executar estes comandos para mover os arquivos:

mv Clima/01d.png 01d.png
mv Clima/01n.png 01n.png
mv Clima/02.png 02d.png
mv Clima/09.png 09.png
mv Clima/11.png 11.png
mv Clima/50.png 50.png

Confirme se os arquivos estão na pasta, utilizando o comando “ls“, se estiverem estamos prontos para a próxima parte do projeto, caso contrário veja qual está faltando e mova para a pasta correta.

Programa

Como já foi instalada a biblioteca para utilizar o display OLED, vamos simplesmente utilizar as bibliotecas “requests” e “json“, que são bibliotecas comuns e já vêm pré-instaladas. A biblioteca “requests” é utilizada para fazer requisições HTTP e receber dados a partir de uma URL. A bilbioteca “json” utilizamos para trabalhar com o formato dos dados que recebemos da requisição.

Utilizando as requisições, vamos buscar dados da previsão do tempo da API OpenWeatherMap de onde é possível extrair informações sobre temperatura, umidade relativa do ar, nebulosidade, histórico de chuvas das últimas horas e afins. Na versão gratuita é possível fazer apenas uma requisição por minuto, portanto se você quiser um acesso mais livre, basta criar o próprio token gratuito no site, de uma forma bem mais fácil do que fizemos com o Twitter. Em posse do token, utilizamos ele para compor a URL da nossa requisição.

Logo do OpenWeatherMap

Este programa é um pouco mais complexo e extenso do que os anteriores, mas como sempre leia com calma e veja os comentários que você será capaz de compreender o código.

## Bibliotecas utilizadas
# Biblioteca do display
import Adafruit_SSD1306
# Ferramentas para o desenho
from PIL import Image, ImageDraw, ImageFont
# Biblioteca que faz requisicoes, utilizada para acessar o OpenWeatherMap
import requests
# Para tratar os dados da requisicao, que vem no formato json
import json


## Usando o OpenWeatherMap
# Com o local e o token definimos a URL da requisicao
local = "itacorubi"
token = "8d6617163b794fa1d2bc398a05ce2047"
url = "http://api.openweathermap.org/data/2.5/forecast?q=" + local + "&appid="+ token + "&units=metric"

# Fazemos a requisicao
res = requests.get(url)
# Separamos os dados no formato .json
dados = res.json()


## Definindo as temperaturas maximas e minimas
lista = dados["list"]

# Valores iniciais para verificar se sao menores ou maiores que esses
min = 999.0
max = -300.0

# Busca o menor e o maior valor nos proximos 8 valores
for i in range(8):
        temp =lista[i]["main"]["temp_min"]
        if temp < min:
            min = temp
        temp = lista[i]["main"]["temp_max"]
        if temp > max:
            max = temp

# Arredonda para valores inteiros
tmin = round(min)
tmax = round(max)


## Definicao do tempo (chuva, sol, nublado)
# Icones de tempo, com os desenhos a serem apresentados na tela
iconeAlt = 21
iconeLar = 60
# Eles sao redimensionados para encaixar no espaco do display
icon_sol = Image.open("01d.png").resize((iconeLar, iconeAlt), Image.ANTIALIAS)
icon_lua = Image.open("01n.png").resize((iconeLar, iconeAlt), Image.ANTIALIAS)
icon_nuvem = Image.open("02.png").resize((iconeLar, iconeAlt), Image.ANTIALIAS)
icon_chuva = Image.open("09.png").resize((iconeLar, iconeAlt), Image.ANTIALIAS)
icon_tempes = Image.open("11.png").resize((iconeLar, iconeAlt), Image.ANTIALIAS)
icon_nevoa = Image.open("50.png").resize((iconeLar, iconeAlt), Image.ANTIALIAS)

# Define o icone de acordo com cada possibilidade de tempo
tempo = lista[0]["weather"][0]["icon"]
# Se a variavel tempo estiver entre essas opcoes, seleciona determinado icone
if tempo == "01d":
    icone = icon_sol
elif tempo == "01n":
    icone =  icon_lua
elif tempo in ["02d", "02n", "03d", "03n", "04d", "04n"]:
    icone = icon_nuvem
elif tempo in ["09d", "09n", "10d", "10n"]:
    icone = icon_chuva
elif tempo in ["11d", "11n"]:
    icone =  icon_tempes
elif tempo in ["50d", "50n"]:
    icone = icon_nevoa
else:
    icone = None

# Informacao da cidade colocada
cidade = dados["city"]["name"]


## Configuracoes do display, vistas na outra aula
# Seleciona o display
disp = Adafruit_SSD1306.SSD1306_128_32(rst=24)

# Inicializa o display
disp.begin()

# Limpa o display
disp.clear()
disp.display()

# Cria uma imagem em branco com a altura e largura do display
# Esta imagem sera modificada para o que desejamos
largura = disp.width
altura = disp.height
imagem = Image.new('1', (largura, altura))

# Cria uma variavel para desenhar na imagem criada
desenha = ImageDraw.Draw(imagem)

# Seleciona a fonte padrao
fonte = ImageFont.load_default()


## A partir daqui, colocamos as informacoes no display
#Posicoes das informacoes na tela
topo = 1
# 3 colunas de informacoes
col1 = 2
col2 = 42
col3 = 70

# Limpa a imagem: desenha um retangulo preto
desenha.rectangle((0, 0, largura, altura), outline=0, fill=0)

# Escreve o nome da cidade
desenha.text((col1, topo), cidade, font=fonte, fill=255)

# Se nao tiver erro, desenha o icone selecionado anteriormente
if not icone is None:
    imagem.paste(icone, (col3, topo +4))

# Escreve os valores da temperatura maximo e minimo
desenha.text((col1+2, topo + 11), "Min", font=fonte, fill=255)
desenha.text((col1, topo + 21), str(tmin) + " °C", font=fonte, fill=255)
desenha.text((col2+2, topo + 11), "Max", font=fonte, fill=255)
desenha.text((col2, topo + 21), str(tmax) + " °C", font=fonte, fill=255)

# Apresenta a imagem desenhada
disp.image(imagem)
disp.display()