Hallo Habr.
Heutzutage verwenden viele Hausautomationsprojekte (und nicht nur) den Raspberry Pi. Gleichzeitig ist es praktisch genug, nicht nur direkten Zugriff auf das Gerät zu haben, sondern auch einen Browser zu verwenden. Auf diese Weise können Sie die erforderlichen Aktionen von einem Computer und einem Mobiltelefon aus und sogar von überall auf der Welt aus ausführen.

Angenommen, wir haben bereits ein Super-Python-Programm, das etwas sehr Wichtiges tut, vom Blinken einer LED bis zur Steuerung eines "Smart Home" oder zumindest eines Katzenfutters. Ich werde verschiedene Möglichkeiten zeigen, von einfach bis komplex, wie man durch Hinzufügen von Code Webzugriff auf eine solche Anwendung ermöglicht.
Der Artikel ist für Anfänger gedacht, die Profis werden hier wahrscheinlich nichts radikal Neues finden, aber ich hoffe, dass er für Linux-Neulinge nützlich sein wird. Für diejenigen, die interessiert sind, weiter unter dem Schnitt.
Hinweis : Dieser Artikel ist eine Art „Experiment“. Einmal in den Kommentaren wurde beanstandet, dass es nicht genug Artikel für Habré für Anfänger gibt. Ich habe versucht, die Lücke zu schließen, aber Schätzungen zufolge wird klar sein, ob es sinnvoll ist, in diesem Format fortzufahren oder nicht.
Also fangen wir an.
Konfigurieren Sie Raspberry Pi
Hoffen wir, dass der Leser einen Raspberry Pi hat, der über WLAN oder Ethernet mit dem Heimnetzwerk verbunden ist, und der Leser weiß, wie die IP-Adresse lautet und wie er sich mit Kitt über SSH remote beim Raspberry Pi anmeldet. Wir werden die sogenannte Headless-Konfiguration betrachten - ohne Tastatur und Monitor. Aber bevor Sie etwas mit dem Raspberry Pi machen, ein paar kleine Life-Hacks.
Tipp N1 . Um mit dem Raspberry Pi etwas aus der Ferne zu tun, müssen Sie SSH darauf konfigurieren. Standardmäßig ist es deaktiviert. Sie können den herkömmlichen Weg gehen und den Standardkonfigurator starten, aber es kann einfacher sein - nach dem Aufzeichnen des Disk-Images erstellen Sie einfach eine leere
SSH- Datei (ohne Erweiterung) im Stammverzeichnis der SD-Karte. Nach dem Laden des Raspberry Pi ist SSH sofort aktiv.
Um remote auf das Gerät zugreifen zu können, müssen Sie die IP-Adresse des Raspberry Pi ermitteln. Öffnen Sie dazu einfach die Systemsteuerung Ihres Routers, suchen Sie dort die Liste der DHCP-Clients, kopieren Sie die gewünschte IP-Adresse von dort (z. B. 192.168.1.102) und geben Sie den Befehl
putty.exe pi@192.168.1.102 (für Windows) oder
ssh pi ein @ 192.168.1.102 für Linux oder OSX.
IP-Adressen können sich jedoch ändern, z. B. nach dem Neustart des Routers. Dies ist nicht immer praktisch. Daraus folgt
Tipp N2 - Konfigurieren Sie eine statische IP-Adresse. Führen Sie dazu den Befehl
sudo nano /etc/dhcpcd.conf auf dem Raspberry Pi aus und geben Sie die folgenden Einstellungen ein:
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
Wenn Sie eine WiFi-Adresse benötigen, ist die Schnittstelle wlan0, wenn Ethernet dann eth0. IP-Adressen müssen Sie natürlich durch Ihre eigenen ersetzen. Stellen Sie nach dem Neustart sicher, dass die IP-Adresse korrekt ist, indem Sie
den Befehl
ifconfig eingeben .
Jetzt ist alles fertig, wir können Python starten. Alle Beispiele sind für Python 3.7 angegeben, da 2.7 seit langem veraltet ist und es keinen Sinn macht, es beizubehalten. Bei kleinen Codeänderungen funktioniert bei Bedarf jedoch alles. Die Python-Sprache ist übrigens plattformübergreifend - dies bedeutet, dass der gesamte unten stehende Code sowohl unter Windows als auch unter OSX und natürlich auf dem Raspberry Pi ausgeführt werden kann. Daraus folgt der
Council N3 : Sie können das Programm auf einem normalen PC debuggen und die fertige Version auf Raspberry Pi hochladen. Möglicherweise müssen Sie nur Wrapper-Funktionen für die GPIO-Methoden erstellen, alles andere funktioniert.
Unsere Aufgabe ist es daher, über einen normalen Browser Zugriff auf die Anwendung zu gewähren. Denn es ist stilvoll, modisch, jugendlich und das „Internet der Dinge“ ist unser Alles.
Methode 1: Befehlszeile
Der einfachste Weg, der überhaupt keine Programmierung erfordert.
Wählen Sie den gewünschten Ordner auf dem Raspberry Pi und geben Sie den folgenden Befehl ein:
python3 -m http.server 5000
Das war's, der Dateiserver läuft auf dem Raspberry Pi! Es reicht aus, auf die Seite
http: //192.168.1.102►000 zu gehen, und wir werden unsere Dateien im Browser sehen:

Dies ist praktisch genug, wenn Sie den Remotezugriff auf Dateien mit minimalem Aufwand öffnen müssen. Sie können auch den Befehl
sudo python3 -m http.server 80 eingeben und den Server mit dem 80. Standardport starten. Dies zeigt den Port nicht in der Adressleiste des Browsers an.
Übrigens, wenn der Server auch nach dem Schließen des Terminals funktionieren soll, können wir den
Befehl sudo nohup python3 -m http.server 80 & verwenden - dies startet den Prozess im Hintergrund. Sie können ein solches Programm beenden, indem Sie es neu
starten oder den Befehl
sudo killall python3 in die Befehlszeile
eingeben .
Methode 2: SimpleHTTPServer
Wir können ganz einfach denselben Server in unser Python-Programm integrieren. Dazu reicht es aus, ihn beim Programmstart in einem separaten Thread zu starten. Jetzt müssen wir uns nicht mehr um die Befehlszeile kümmern, während das Programm ausgeführt wird, funktioniert der Server.
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()
Der Befehl os.chdir ist optional, wenn Sie vom Server aus auf einen anderen Ordner als den aktuellen zugreifen möchten.
Methode 3: HTTPServer
Dies ist bereits ein vollwertiger Webserver, der GET- und POST-Anforderungen verarbeiten, verschiedene Daten zurückgeben usw. Aber natürlich benötigen Sie mehr Code.
Betrachten Sie die minimal funktionierende Version des Servers:
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)
Wir starten den Browser und sehen unsere HTML-Seite darin:

Dieser Server ist leicht zu erlernen, um Dateien wie Bilder zu geben.
Fügen Sie das img-Tag zum HTML hinzu:
html = '<html><body><h3>Hello from the Raspberry Pi</h3><img src="raspberrypi.jpg"/></body></html>'
Die Quelldatei „raspberrypi.jpg“ muss sich natürlich im Programmordner befinden. Fügen Sie der Funktion do_GET die Möglichkeit zum Empfangen von Dateien hinzu:
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))
Wir starten den Server und sehen das entsprechende Bild:

Es ist unwahrscheinlich, dass ein solcher Server den Webdesign-Wettbewerb gewinnt, aber es funktioniert recht gut. Der Server kann leicht gezwungen werden, nützlichere Daten anzugeben, um beispielsweise Informationen über den Betrieb des Programms zurückzugeben. Fügen Sie beispielsweise einen Handler für die neue Statusfunktion hinzu:
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'))
Jetzt können wir den Link
http: //192.168.1.102►000/status im Browser öffnen und die aktuellen Systemparameter
anzeigen :

Wie Sie sehen, senden wir die Daten übrigens im JSON-Format, sodass wir sie für einige andere Anfragen verwenden können.
Fazit
Alle in einem Stück konzipierten passten nicht. Der zweite Teil
ist hier verfügbar .
Wichtig: SicherheitsmaßnahmenWenn für den Raspberry Pi eine externe IP-Adresse verwendet wird, sollten Sie unbedingt die Sicherheitsmaßnahmen berücksichtigen. Es mag den Anschein haben, dass niemand Ihren Mini-Server benötigt, aber jetzt ist es einfach, alle IP-Adressbereiche (z. B.
Ukraine ,
Österreich ) stapelweise zu scannen und alle verfügbaren Geräte zu finden. Sie sollten daher auf
jeden Fall das Kennwort auf dem Raspberry Pi ändern und keine vertraulichen Informationen auf dem Gerät speichern (Dropbox-Ordner, Namen / Kennwörter, die in Skripten, Fotos usw. fest codiert sind).
PS: Eine Umfrage wurde hinzugefügt, um das Bild zu verstehen