Dashboard na Raspberry Pi usando Python

Dashboard na Raspberry Pi usando Python Deixe um comentário

Um dashboard (ou “painel de controle”) é uma imagem que apresenta informações necessárias para acompanhar um processo. É muito comum utilizar gráficos para facilitar a visualização das informações. Neste artigo vamos ver uma forma de implementar um dashboard na Raspberry Pi utilizando uma aplicação Python que cria diretamente a imagem a partir dos dados, usando a biblioteca matplotlib.

As placas Raspberry Pi são bem adequadas para apresentação de dashboards, sejam ligadas a monitores pequenos ou a TVs.  No nosso exemplo dados fictícios serão criados pelo programa, caso essa solução fosse utilizada em uma aplicação real as informações poderiam ser obtidos de uma base de dados ou de uma API.

Exemplo de apresentação de dashboards
Exemplo de apresentação de dashboards

Material Necessário para fazer um Dashboard na Raspberry

Embora a aplicação que vamos ver possa ser usada em praticamente qualquer configuração de Raspberry Pi, da Zero até a 4, o desempenho dependerá do modelo usado (principalmente a apresentação inicial). Recomendo usar uma Raspberry Pi Zero W 2 ou uma Raspberry Pi 4.

Para a Raspberry Pi Zero você vai precisar:

  • Placa Raspberry Pi Zero W
  • Cabo micro USB e fonte USB para alimentação
  • Cabo mini HDMI x HDMI para conexão ao monitor ou TV
  • Cartão micro SD
  • Adaptador OTG e hub USB para conexão de teclado e mouse durante o desenvolvimento (alternativamente você pode usar SSH ou VNC para operar o Pi remotamente).

Para a Raspberry Pi 4:

  • Placa Raspberry Pi 4
  • Cabo USB-C e fonte USB para alimentação
  • Cabo micro HDMI x HDMI para conexão ao monitor ou TV
  • Cartão micro SD

Preparação para criação do Dashboard

Utilize o Raspberry Pi Imager para gravar o Raspberry Pi OS (32-bit) no cartão SD. Antes de disparar a gravação, através das opções avançadas, configure:

  1. Enable SSH / use password authentication
  2. Username pi e um password de sua preferência
  3. A rede WiFi onde você irá se conectar
  4. As preferências de local
Uma tela Raspberry Pi Imager aberta nas configuerações
Configurações na Raspberry Pi Imager

Após a gravação, coloque o cartão SD na Raspberry e conecte o teclado e mouse (se for usar) e o monitor (ou TV). Por último ligue a alimentação e aguarde o desktop ser apresentado. Abra uma janela de comando ou se conecte via ssh e digite os comandos abaixo:

sudo apt update
sudo apt-get install python3-matplotlib

A Biblioteca Matplotlib

A Matplotlib é uma biblioteca Python para desenho de gráficos; o site oficial é https://matplotlib.org/. É uma biblioteca bem poderosa, porém vamos ver aqui apenas as funcionalidades básicas. Caso tenha interesse em aprender mais, o site oficial contém tutoriais e a documentação completa.

Atenção: A versão instalada pelo apt-get pode ser mais antiga do que a última apresentada no site. No momento em que fiz os testes a versão instalada pelo apt-get foi a 3.3.4 e a versão mais recente era a 3.6.0.

O módulo principal da matplotlib é pyplot. O método subplots cria uma figura e um conjunto de eixos (gráficos) organizados em uma tabela. Chamando métodos dos eixos, nós criamos os gráficos propriamente ditos. Vejamos um pequeno exemplo:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2 * np.pi, 20)
y = np.sin(x)

fig, ax = plt.subplots(2,2)
ax[0,0].plot(x, y)
ax[0,1].scatter(x, y)
ax[1,0].step(x, y)
ax[1,1].bar(x, y)
plt.show()

Os tipos de gráfico disponíveis podem ser vistos em https://matplotlib.org/stable/plot_types/index.html. Se você rodar esse exemplo, usando a IDE Thonny que vem com o Raspberry Pi OS, vai ver que ele é apresentado em uma janela que tem uma barra de controle (toolbar) na parte inferior:

Exemplo de gráficos disponíveis
Exemplo de gráficos disponíveis

Se você pretende apresentar a dashboard sem que as pessoas interajam com ele, podemos colocar em tela cheia e esconder o toolbar:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2 * np.pi, 20)
y = np.sin(x)

mpl.rcParams['toolbar'] = 'None'

fig, ax = plt.subplots(2,2)
ax[0,0].plot(x, y)
ax[0,1].scatter(x, y)
ax[1,0].step(x, y)
ax[1,1].bar(x, y)
mng = plt.get_current_fig_manager()
mng.full_screen_toggle()
plt.show()


Se você rodar com um teclado conectado, poderá usar atalhos como:

 

Tecla

Função

q

Fecha a figura

f

Ligar/desligar modo tela cheia

p

Selecionar entre Pan e Zoom

Até agora as imagens estão estáticas. Quando plt.show() é chamado a figura é apresentada e a execução só retorna quando ela é fechada. Este é o modo “não interativo” da matplotlib. Para podermos atualizar as imagens, vamos ligar o modo “interativo” e usar o método plt.pause() para tratar o teclado por alguns segundos e depois continuar com o programa:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2*np.pi, 20)
y = np.sin(x)

plt.ion()

fig, ax = plt.subplots(2,1)

ax[0,0].plot(x, y)
ax[0,1].scatter(x, y)

while True:
    plt.pause(5)
    if len(plt.get_fignums()) == 0:
        break
    ax[0,0].clear()
    y = -y
    ax[0,0].plot(x, y)

 

É possível personalizar várias características dos gráficos. Alguns exemplos:

set_title('Umidade Relativa')

Define o título do gráfico

set_facecolor('xkcd:light teal')

Define a cor de fundo do gráfico. Adiante explico como especificar uma cor.

set_ylabel('Tensão')

Define a legenda do eixo Y

set_xlabel('Dia da Semana')

Define a legenda do eixo X

set_xticks(x_ticks)

Define as marcas no eixo X.

yaxis.set_data_interval(ymin, ymax)

 

Define os valores mínimo e máximo no eixo Y. Se os dados saírem fora deste intervalo, o intervalo é ampliado. No lugar de “yaxis” pode ser usado “xaxis” para o eixo X.

Existem várias formas de especificar as cores, algumas delas:

  • (r, g, b) onde r, g e b são as intensidades entre 0 e 1 de vermelho, verde e azul. Exemplo: (0.4, 0.6, 0.1)
  • ‘#rrggbb’ onde rr, gg e bb são as intensidades de vermelho, verde e azul em hexadecimal (00 a FF)
  • ‘nome’ onde nome é o nome da cor no CSS 4 (sem espaços)
  • ‘xkcd: nome’ onde nome é o nome da cor conforme https://xkcd.com/color/rgb/

Dica: Se você deseja fazer gráficos estatísticos mais sofisticados com maior facilidade, dê uma olhada na biblioteca seaborn (https://seaborn.pydata.org/index.html) que é uma camada adicional sobre a matplotlib.

Exemplo de Dashboard

O exemplo abaixo mostra um dashboard para apresentar informações simuladas de temperatura e umidade, como as que obteríamos conectando sensores como o DHT11 (veja como fazer isso aqui):

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# Cria os dados simulados
# xh = eixo X de 24 horas com passo de 10 minutos
# xd = eixo X de 4 semanas
# yud_min, yud_max, yud_med = umidade diaria
# ytd_min, ytd_max, ytd_med = temperatura diaria
# yu = umidade a cada 10 minutos
# yt = temperatura a cada 10 minutos
xh = np.linspace(0, 24, 6*24)
xd = np.linspace(1, 4*7, 4*7)
yud_med = np.random.randint(30, high=80, size=4*7)
yud_max = yud_med + np.random.randint(5, high=15, size=4*7)
yud_min = yud_med + np.random.randint(-15, high=-5, size=4*7)
ytd_med = np.random.randint(10, high=35, size=4*7)
ytd_max = ytd_med + np.random.randint(1, high=5, size=4*7)
ytd_min = ytd_med + np.random.randint(-5, high=-1, size=4*7)
x1 = np.linspace(0, 8*np.pi, 6*24)
x2 = np.linspace(3, 15*np.pi, 6*24)
yu = 45+20*np.sin(x1)+20*np.sin(x2)
x = np.linspace(-2.0, 2*np.pi-2, 6*24)
yt = 15+5*np.sin(x)
tickh = np.linspace(0, 24, 7)

# Cria os gráficos
mpl.rcParams['toolbar'] = 'None'
plt.ion()
fig, ax = plt.subplots(2,2)
fig.set_facecolor('xkcd:eggshell')

def plotUmidade():
    ax[0,0].plot(xh, yu)
    ax[0,0].set_ylabel('%')
    ax[0,0].yaxis.set_data_interval(0, 100)
    ax[0,0].set_title('Umidade Relativa')
    ax[0,0].set_xticks(tickh)
    ax[0,0].set_facecolor('xkcd:light teal')

def plotTemperatura():
    ax[0,1].plot(xh, yt)
    ax[0,1].set_ylabel('Centígrados')
    ax[0,1].yaxis.set_data_interval(0, 40)
    ax[0,1].set_title('Temperatura')
    ax[0,1].set_xticks(tickh)
    ax[0,1].set_facecolor('xkcd:ivory')

plotUmidade()
plotTemperatura()
line_med, = ax[1,0].plot(xd, yud_med, label='Média')
line_max, = ax[1,0].plot(xd, yud_max, label='Máximo')
line_min, = ax[1,0].plot(xd, yud_min, label='Mínimo')
ax[1,0].set_xlabel('Dias anteriores')
ax[1,0].set_ylabel('%')
ax[1,0].yaxis.set_data_interval(0, 100)
ax[1,0].set_xticks([])
ax[1,0].set_facecolor('xkcd:celadon')
ax[1,0].legend(handles=[line_med, line_max, line_min], loc='upper right')

line_med, = ax[1,1].plot(xd, ytd_med, label='Média')
line_max, = ax[1,1].plot(xd, ytd_max, label='Máximo')
line_min, = ax[1,1].plot(xd, ytd_min, label='Mínimo')
ax[1,1].set_ylabel('Centígrados')
ax[1,1].yaxis.set_data_interval(0, 40)
ax[1,1].set_title('Temperatura')
ax[1,1].set_xticks([])
ax[1,1].set_facecolor('xkcd:cream')
ax[1,1].legend(handles=[line_med, line_max, line_min], loc='upper right')

# Operar em tela cheia
mng = plt.get_current_fig_manager()
mng.full_screen_toggle()

# Loop de atualização
while True:
    plt.pause(5)
    if len(plt.get_fignums()) == 0:
        break
    yt = np.roll(yt,1)
    yu = np.roll(yu,1)
    ax[0,0].clear()
    plotUmidade()
    ax[0,1].clear()
    plotTemperatura()

O resultado pode ser visto na foto no início do artigo.

Rodando o Dashboard ao ligar o Raspberry Pi

Abra uma janela de comando ou se conecte via ssh. Use “sudo raspi-config” para conferir que Desktop Auto Login está selecionado em > System Options > Boot > Auto Login.

Em seguida digite “sudo nano /etc/xdg/autostart/Dashboard.desktop” e entre com os comandos abaixo:

[Desktop Entry]
Type=Application
Name=Dashboard
Exec=python /home/pi/dashboard.py

(Troque “/home/pi/dashboard.py” pelo nome do seu programa Python que desenha o dashboard)

Salve o arquivo com Control X Y e reinicie o Raspberry (“sudo reboot”). O Raspberry Pi será reiniciado e o dashboard será executado automaticamente.

Conclusão

Um dashboard é um instrumento muito útil na monitoração de sensores e outras informações. Usando um Raspberry Pi ligado a um monitor ou TV podemos construir facilmente um dashboard bonito e compacto.

Está animado para construir os dashboards? Coloque nos comentários os seus resultados e as suas dúvidas. E não esqueça de nos seguir a MakerHero no Instagram para acompanhar mais novidades e projetos incríveis. 

Faça seu comentário

Acesse sua conta e participe