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.

setup_web

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

Kepler Kit

Die einzelnen Komponenten können Sie auch über die folgenden Links erwerben.

SN

KOMPONENTE

ANZAHL

LINK

1

Raspberry Pi Pico W

1

BUY

2

Micro-USB-Kabel

1

3

Steckbrett

1

BUY

4

Jumperkabel

Mehrere

BUY

5

Widerstand

4(1-330Ω, 2-220Ω, 1-10KΩ)

BUY

6

RGB-LED

1

BUY

7

Thermistor

1

BUY

8

Li-Po-Lademodul

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.

../_images/7.web_page_bb.png

3. Code ausführen

  1. Öffnen Sie die Datei 7_web_page.py im Ordner kepler-kit-main/iot.

  2. 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.

    ../_images/7_web_server.png

    Bemerkung

    Bevor Sie den Code ausführen, stellen Sie sicher, dass die Skripte do_connect.py und secrets.py auf Ihrem Pico W vorhanden sind. Wenn nicht, folgen Sie den Anweisungen unter 1. Zugang zum Netzwerk, um sie zu erstellen.

  3. 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.

    ../_images/web-1.png
  4. 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()