7. Ein Webserver einrichten¶
In diesem Artikel erfahren Sie, wie Sie den Pico W in einen Webserver verwandeln, über den Sie Schaltkreise steuern und Sensordaten direkt aus Ihrem Browser abrufen können.
1. Benötigte Komponenten
Für dieses Projekt benötigen Sie die folgenden Bauteile.
Ein komplettes Bausatz ist natürlich praktisch. Hier ist der Link dazu:
Bezeichnung |
BESTANDTEILE IN DIESEM KIT |
LINK |
---|---|---|
Kepler Kit |
Über 450 |
Die einzelnen Komponenten können Sie auch über die folgenden Links erwerben.
SN |
KOMPONENTE |
ANZAHL |
LINK |
---|---|---|---|
1 |
1 |
||
2 |
Micro-USB-Kabel |
1 |
|
3 |
1 |
||
4 |
Mehrere |
||
5 |
4(1-330Ω, 2-220Ω, 1-10KΩ) |
||
6 |
1 |
||
7 |
1 |
||
8 |
1 |
||
9 |
18650-Batterie |
1 |
|
10 |
Batteriehalter |
1 |
2. Schaltung aufbauen
Warnung
Achten Sie darauf, dass Ihr Li-Po-Ladegerät genau wie im Schaltplan angeschlossen ist. Andernfalls könnte ein Kurzschluss Ihre Batterie und die Schaltung beschädigen.
3. Code ausführen
Öffnen Sie die Datei
7_web_page.py
im Ordnerkepler-kit-main/iot
.Klicken Sie auf die Schaltfläche Aktuelles Skript ausführen oder drücken Sie F5. Nach erfolgreicher Verbindung wird die IP-Adresse des Pico W angezeigt.
Bemerkung
Bevor Sie den Code ausführen, stellen Sie sicher, dass die Skripte
do_connect.py
undsecrets.py
auf Ihrem Pico W vorhanden sind. Wenn nicht, folgen Sie den Anweisungen unter 1. Zugang zum Netzwerk, um sie zu erstellen.Geben Sie die IP-Adresse des Pico W in Ihren Browser ein, um die für dieses Projekt erstellte Webseite aufzurufen. Klicken Sie auf einen beliebigen Button, um die Farbe der RGB-LEDs zu ändern und die Temperatur sowie die Luftfeuchtigkeit zu aktualisieren.
Wenn Sie möchten, dass dieses Skript beim Start ausgeführt wird, speichern Sie es als
main.py
auf dem Raspberry Pi Pico W.
Wie funktioniert es?
Die Webseite, die Sie besuchen, wird tatsächlich auf einem Server gehostet. Der Socket auf dem Server sendet uns die Webseite, sobald wir sie aufrufen. Ein Socket ist die Methode, mit der ein Server auf einen Client hören kann, der eine Verbindung herstellen möchte.
In diesem Projekt fungiert Pico W als Ihr Server, und Ihr Computer greift über einen Browser auf die auf Pico W gehostete Webseite zu.
Zuerst erstellen wir einen Socket, der eine IP-Adresse und einen port benötigt. Details zur Netzwerkverbindung und zur Ermittlung der IP-Adresse finden Sie unter 1. Zugang zum Netzwerk. Als Port verwenden wir 80. Nachdem der Socket eingerichtet ist, geben wir ihn zurück und verwenden ihn für den nächsten Schritt.
Socket-Bibliothek - Python Docs
import socket
def open_socket(ip):
# Einen Socket öffnen
address = (ip, 80)
connection = socket.socket()
connection.bind(address)
connection.listen(1)
print(connection)
return connection
Anschließend richten Sie Ihren Webdienst ein, bei dem der zuvor eingerichtete Socket zum Einsatz kommt. Der folgende Code ermöglicht es Ihrem Pico W, Zugriffsanfragen von Ihrem Browser entgegenzunehmen.
def serve(connection):
while True:
client = connection.accept()[0]
request = client.recv(1024)
client.close()
Als Nächstes benötigen Sie eine HTML-Seite, die Sie dem Besucher senden können. Dieses Beispiel speichert eine einfache HTML-Seite in Form von Zeichen in der Variablen html
.
Bemerkung
Wenn Sie in der Lage sein möchten, Ihr eigenes HTML zu schreiben, können Sie Hilfe unter HTML.COM finden.
def webpage(value):
html = f"""
<!DOCTYPE html>
<html>
<body>
<form action="./red">
<input type="submit" value="Rot" />
</form>
<form action="./green">
<input type="submit" value="Grün" />
</form>
<form action="./blue">
<input type="submit" value="Blau" />
</form>
<form action="./off">
<input type="submit" value="Aus" />
</form>
<p>Die Temperatur beträgt {value} Grad Celsius</p>
</body>
</html>
"""
return html
HTML-Seite an den Besucher senden.
def serve(connection):
while True:
client = connection.accept()[0]
request = client.recv(1024)
html=webpage(0)
client.send(html)
client.close()
Die Seite kann über Ihren Browser aufgerufen werden, wenn Sie die oben genannten Teile kombinieren. Um die Wirkung zu sehen, führen Sie den unten stehenden Code mit Thonny aus.
import machine
import socket
from secrets import *
from do_connect import *
def webpage(value):
html = f"""
<!DOCTYPE html>
<html>
<body>
<form action="./red">
<input type="submit" value="red " />
</form>
<form action="./green">
<input type="submit" value="green" />
</form>
<form action="./blue">
<input type="submit" value="blue" />
</form>
<form action="./off">
<input type="submit" value="off" />
</form>
<p>Temperature is {value} degrees Celsius</p>
</body>
</html>
"""
return html
def open_socket(ip):
# Open a socket
address = (ip, 80)
connection = socket.socket()
connection.bind(address)
connection.listen(1)
print(connection)
return(connection)
def serve(connection):
while True:
client = connection.accept()[0]
request = client.recv(1024)
html=webpage(0)
client.send(html)
client.close()
try:
ip=do_connect()
if ip is not None:
connection=open_socket(ip)
serve(connection)
except KeyboardInterrupt:
machine.reset()
Wenn Sie den obigen Code ausführen, werden Sie feststellen, dass lediglich eine Webseite angezeigt wird; eine Steuerung der RGB-LEDs oder die Anzeige von Sensorwerten ist nicht möglich. Der Webdienst muss weiter verfeinert werden.
Zunächst müssen wir wissen, welche Informationen der Server erhält, wenn der Browser auf die Webseite zugreift. Ändern Sie deshalb die Funktion serve()
geringfügig, um request
auszugeben.
def serve(connection):
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
print(request)
html=webpage(0)
client.send(html)
client.close()
Führen Sie das Skript erneut aus, und die Shell wird die folgende Nachricht ausgeben, wenn wir eine Taste auf der Webseite drücken.
b'GET /red? HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'
b'GET /favicon.ico HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'
b'GET /blue? HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'
b'GET /favicon.ico HTTP/1.1\r\nHost: 192.168.18.162\r\nConnection: keep-alive.......q=0.5\r\n\r\n'
Das ist zu viel zum Lesen!
Was wir wirklich benötigen, ist jedoch nur der kleine Informationsbrocken vor /red?
, /blue?
.
Er zeigt uns an, welcher Knopf gedrückt wurde. Deshalb haben wir serve()
leicht modifiziert, um die Tasteninformation zu extrahieren.
def serve(connection):
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
try:
request = request.split()[1]
except IndexError:
pass
print(request)
html=webpage(0)
client.send(html)
client.close()
Führen Sie das Programm erneut aus, und die Shell wird die folgende Nachricht ausgeben, wenn wir eine Taste auf der Webseite drücken.
/red?
/favicon.ico
/blue?
/favicon.ico
/off?
/favicon.ico
Anschließend müssen wir nur noch die Farbe der RGB-LED entsprechend dem Wert von request
ändern.
def serve(connection):
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
try:
request = request.split()[1]
except IndexError:
pass
print(request)
if request == '/off?':
red.low()
green.low()
blue.low()
elif request == '/red?':
red.high()
green.low()
blue.low()
elif request == '/green?':
red.low()
green.high()
blue.low()
elif request == '/blue?':
red.low()
green.low()
blue.high()
html=webpage(0)
client.send(html)
client.close()
Zuletzt soll der Thermistorwert auf der Webseite angezeigt werden (siehe 2.13 Thermometer für Details zur Verwendung des Thermistors).
Dies wird tatsächlich durch Ändern des Texts im HTML erreicht.
Wir setzen die Parameter in der Funktion webpage(value)
und ändern einfach die eingehenden Parameter, um die auf der Webseite angezeigte Zahl zu ändern.
def serve(connection):
while True:
client = connection.accept()[0]
request = client.recv(1024)
request = str(request)
try:
request = request.split()[1]
except IndexError:
pass
#print(request)
if request == '/off?':
red.low()
green.low()
blue.low()
elif request == '/red?':
red.high()
green.low()
blue.low()
elif request == '/green?':
red.low()
green.high()
blue.low()
elif request == '/blue?':
red.low()
green.low()
blue.high()
value='%.2f'%temperature()
html=webpage(value)
client.send(html)
client.close()