Oi Habr.
Hoje, um grande número de projetos de automação residencial (e não apenas) usa o Raspberry Pi. Ao mesmo tempo, é conveniente o suficiente não apenas ter acesso direto ao dispositivo, mas também usar um navegador - isso permite que você execute as ações necessárias em um computador, telefone celular e até remotamente de qualquer lugar do mundo.

Suponha que já tenhamos um programa super Python que faça algo muito importante, desde a piscar de um LED até o controle de uma "casa inteligente" ou pelo menos um alimentador de gatos. Mostrarei maneiras diferentes, do simples ao complexo, de como acessar a Web a esse aplicativo adicionando algum código.
O artigo é destinado a iniciantes, é improvável que os profissionais encontrem algo fundamentalmente novo aqui, mas espero que seja útil para iniciantes no Linux. Para aqueles que estão interessados, continuaram sob o corte.
Nota : este artigo é uma espécie de "experimento", uma vez nos comentários eles reclamaram que não havia artigos suficientes para Habré para iniciantes. Tentei preencher a lacuna, mas, por estimativas, ficará claro se faz sentido continuar nesse formato ou não.
Então, vamos começar.
Configurar Raspberry Pi
Esperamos que o leitor tenha um Raspberry Pi conectado à rede doméstica via Wi-Fi ou Ethernet, e o leitor saiba qual é o endereço IP e como efetuar login remotamente no Raspberry Pi via SSH usando massa de vidraceiro. Vamos considerar a chamada configuração sem cabeça - sem teclado e monitor. Mas antes de fazer algo com o Raspberry Pi, alguns pequenos hacks da vida.
Dica N1 . Para fazer algo remotamente com o Raspberry Pi, você precisa configurar o SSH e, por padrão, está desativado. Você pode seguir o caminho tradicional e iniciar o configurador padrão, mas pode ser mais simples - depois de gravar a imagem do disco, basta criar um arquivo
ssh vazio (sem extensão) na raiz do cartão SD. Além disso, após o carregamento do Raspberry Pi, o SSH estará imediatamente ativo.
Para acessar o dispositivo remotamente, você precisa descobrir o endereço IP do Raspberry Pi. Para fazer isso, basta abrir o painel de controle do seu roteador, localizar a lista de clientes DHCP, copiar o endereço IP desejado (por exemplo, será 192.168.1.102) e digite o comando
putty.exe pi@192.168.1.102 (para Windows) ou
ssh pi @ 192.168.1.102 para Linux ou OSX.
No entanto, os endereços IP podem mudar, por exemplo, após a reinicialização do roteador, isso nem sempre é conveniente. A seguir,
dica N2 - configure um endereço IP estático. Para fazer isso, execute o comando
sudo nano /etc/dhcpcd.conf no Raspberry Pi e insira as seguintes configurações:
interface eth0 static ip_address=192.168.1.152/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1 8.8.8.8
Se você precisar de um endereço WiFi, a interface será wlan0, se Ethernet, então eth0. É claro que você precisa substituir os seus endereços IP. Após a reinicialização, verifique se o endereço IP está correto
emitindo o comando
ifconfig .
Agora tudo está pronto, podemos iniciar o Python. Todos os exemplos são dados para o Python 3.7, porque o 2.7 está obsoleto e não faz sentido mantê-lo. Mas com pequenas alterações de código, tudo funcionará lá, se necessário. A propósito, a linguagem Python é multiplataforma - isso significa que todo o código abaixo pode ser executado no Windows e no OSX e, é claro, no Raspberry Pi. O
Council N3 segue a partir disso - você pode depurar o programa em um PC comum e carregar a versão final no Raspberry Pi. Talvez você precise criar funções de wrapper para os métodos GPIO; tudo o resto funcionará.
Portanto, nossa tarefa é fornecer acesso ao aplicativo por meio de um navegador regular. Pois é elegante, moderno, jovem e a “Internet das coisas” é o nosso tudo.
Método 1: linha de comando
A maneira mais fácil, sem necessidade de programação.
Selecione a pasta desejada no Raspberry Pi e digite o comando:
python3 -m http.server 5000
É isso, o servidor de arquivos é executado no Raspberry Pi! Basta acessar a página
http: //192.168.1.102►000 e veremos nossos arquivos no navegador:

Isso é conveniente o suficiente se você precisar abrir o acesso remoto a qualquer arquivo com o mínimo de esforço. Você também pode inserir o comando
sudo python3 -m http.server 80 e iniciar o servidor com a 80ª porta padrão; isso não indicará a porta na barra de endereços do navegador.
A propósito, se queremos que o servidor funcione mesmo após o fechamento do terminal, podemos usar o
comando sudo nohup python3 -m http.server 80 & - isso iniciará o processo em segundo plano. Você pode matar esse programa reiniciando ou inserindo o comando
sudo killall python3 na linha de comando.
Método 2: SimpleHTTPServer
Podemos simplesmente integrar o mesmo servidor ao nosso programa Python, para isso basta iniciar em um thread separado no início do programa. Agora, não precisamos nos preocupar com a linha de comando. Enquanto o programa estiver em execução, o servidor funcionará.
import http.server import socketserver from threading import Thread import os def server_thread(port): handler = http.server.SimpleHTTPRequestHandler with socketserver.TCPServer(("", port), handler) as httpd: httpd.serve_forever() if __name__ == '__main__': port = 8000 print("Starting server at port %d" % port) os.chdir("/home/pi/Documents") Thread(target=server_thread, args=(port,)).start()
O comando os.chdir é opcional se desejarmos fornecer acesso do servidor para outra pasta que não a atual.
Método 3: HTTPServer
Este já é um servidor Web completo, capaz de processar solicitações GET e POST, retornar dados diferentes, etc. Mas é claro, você precisará de mais código.
Considere a versão minimamente funcional do servidor:
from http.server import BaseHTTPRequestHandler, HTTPServer html = "<html><body>Hello from the Raspberry Pi</body></html>" class ServerHandler(BaseHTTPRequestHandler): def do_GET(self): if self.path == "/": self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(html.encode('utf-8')) else: self.send_error(404, "Page Not Found {}".format(self.path)) def server_thread(port): server_address = ('', port) httpd = HTTPServer(server_address, ServerHandler) try: httpd.serve_forever() except KeyboardInterrupt: pass httpd.server_close() if __name__ == '__main__': port = 8000 print("Starting server at port %d" % port) server_thread(port)
Iniciamos o navegador e vemos nossa página HTML:

É fácil ensinar esse servidor a fornecer arquivos, como imagens.
Adicione a tag img ao HTML:
html = '<html><body><h3>Hello from the Raspberry Pi</h3><img src="raspberrypi.jpg"/></body></html>'
O arquivo de origem “raspberrypi.jpg”, é claro, deve estar na pasta do programa. Adicione a capacidade de receber arquivos à função do_GET:
def do_GET(self): print("GET request, Path:", self.path) if self.path == "/": self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(html.encode('utf-8')) elif self.path.endswith(".jpg"): self.send_response(200) self.send_header('Content-type', 'image/jpg') self.end_headers() with open(os.curdir + os.sep + self.path, 'rb') as file: self.wfile.write(file.read()) else: self.send_error(404, "Page Not Found {}".format(self.path))
Iniciamos o servidor e vemos a imagem correspondente:

É improvável que esse servidor vença o concurso de web design, mas funciona muito bem. O servidor pode ser facilmente forçado a fornecer dados mais úteis, por exemplo, retornar informações sobre a operação do programa. Por exemplo, adicione um manipulador para a nova função de status:
import psutil import json def cpu_temperature(): return psutil.sensors_temperatures()['cpu-thermal'][0].current def disk_space(): st = psutil.disk_usage(".") return st.free, st.total def cpu_load() -> int: return int(psutil.cpu_percent()) def ram_usage() -> int: return int(psutil.virtual_memory().percent) def do_GET(self): ... elif self.path == "/status": self.send_response(200) self.send_header('Content-Type', 'application/json') self.end_headers() health = {'CPUTemp': cpu_temperature(), 'CPULoad': cpu_load(), "DiskFree": disk_space()[0], "DiskTotal": disk_space()[1], "RAMUse": ram_usage()} self.wfile.write(json.dumps(health).encode('utf-8'))
Agora podemos abrir o link
http: //192.168.1.102►000/status no navegador e ver os parâmetros atuais do sistema:

A propósito, como você pode ver, enviamos os dados no formato JSON, o que nos permitirá usá-los para outras solicitações.
Conclusão
Todos concebidos em uma peça não se encaixam. A segunda parte
está disponível aqui .
Importante: medidas de segurançaSe um endereço IP externo for usado para o Raspberry Pi, você deve ter sempre em mente as medidas de segurança. Pode parecer que ninguém precisa do seu mini-servidor, mas agora é fácil digitalizar em lote todos os intervalos de endereços IP (por exemplo,
Ucrânia ,
Áustria ) e encontrar todos os dispositivos disponíveis. Portanto, você
definitivamente deve alterar a senha no Raspberry Pi e não deve armazenar nenhuma informação confidencial no dispositivo (pastas do Dropbox, nomes / senhas codificados em scripts, fotos etc.).
PS: Foi adicionada uma pesquisa para entender a imagem