Pico 2 W Projekte

getestet in CircuitPython 9.2.5

Webserver zur Smart Home Steuerung mit Relais


Bildbox 1 (klick hier)

Software

- CircuitPython 9.2.5
- Bibliotheken im 'lib'-Ordner
    - Ordner: adafruit_bme280
    - Ordner: adafruit_httpserver
    - adafruit_connection_manager.mpy
    - adafruit_requests.mpy
- Datei 'settings.toml' mit den Zugangsdaten zum WLAN-Netz

Auf dem oberen Bild ist noch einmal das Relaisboard von SB-Components zu sehen. In der Steuerung sollen die folgenden Funktionen realisiert werden:

Relais 1:
Der Temperatursensor erfasst kontinuierlich die aktuelle Temperatur und schaltet bei einem vorgegebenen Sollwert einen Lüfter ein bzw. aus.

Relais 2:
Es wird über den Helligkeitssensor als Dämmerungsschalter genutzt, welcher eine Beleuchtung steuert.

Relais 3:
Steuert ebenfalls eine Lampe, aber ohne einen angeschlossenen Sensor. Mit Hilfe einer Internetverbindung werden die jeweils aktuellen Sonnenauf- bzw. Sonnenuntergangszeiten (Sunrise/ Sunset) abgerufen und danach eine Beleuchtung gesteuert.

Relais 4:
Mit Hilfe des Infrarotsensors (Bewegungsmelder) wird eine Bewegung in der Umgebung registriert und eine Lampe eingeschaltet.

Alle vier Funktionen laufen automatisch. Bei Bedarf lassen sich die Verbraucher aber unabhängig voneinander manuell steuern. Dazu wird mit dem Pico 2W ein Webserver im WLAN bereitgestellt. Über eine Website mit entsprechenden Button erfolgt dann die Steuerung.


Auf der unteren Abbildung zeige ich den Anschluss des Temperatur-, des Licht- und des Bewegungssensors an den Pico 2 W. Der Aufbau ist identisch mit dem vorherigen Versuch (siehe hier).


Nachfolgend zeige und beschreibe ich schrittweise den Programmcode. In den Zeilen 1 bis 13 werden die notwendigen Bibliotheken importiert. In den Zeilen 15 bis 22 werden die Schwellwerte zum Schalten des Lüfters und des Dämmerungsschaltes festgelegt. Experimentieren Sie ruhig damit. Wenn Sie Änderungen vornehmen, wirken sich diese im gesamten Programm aus. Dann folgen ab Zeile 24 die Definitionen für die Onboard-LED, den Temperatursensor, den Lichtsensor und den Bewegungssensor.

  
  
1   import time
2   import board
3   import busio
4   import ssl
5   import wifi
6   import adafruit_requests
7   import socketpool
8   import digitalio
9   from digitalio import DigitalInOut, Direction
10  from analogio import AnalogIn
11  from adafruit_connection_manager import get_radio_socketpool
12  from adafruit_httpserver import Server, Request, Response, POST
13  from adafruit_bme280 import basic as adafruit_bme280
14
15  ###
16  #  Schwellwerte festlegen
17  ###
18  # Temperaturwerte ein/aus
19  tempon = 25
20  tempoff = 24
21  # Schaltschwelle des Lichtsensors
22  soll_wert = 11000
23
24  #  onboard LED setup
25  led = DigitalInOut(board.LED)
26  led.direction = Direction.OUTPUT
27  led.value = False
28
29  #I2C Pin of the PicoBoy - Color
30  SDA = board.GP0
31  SCL = board.GP1
32  # Create sensor object, using the board's default I2C bus.
33  i2c = busio.I2C(SCL, SDA)
34  bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, address=0x77)
35
36  #initialisieren des Analogen Pin 33 | GP28
37  ADC_2 = AnalogIn(board.GP28)
38
39  # Setup digital inputs for PIR sensor:
40  pir = digitalio.DigitalInOut(board.GP22)
41  pir.direction = digitalio.Direction.INPUT
42  pir.pull = digitalio.Pull.UP
43
  

Es folgen die Zeiten 'sunrise' und 'sunset'. Dazu wird eine Anfrage an die Seite https://api.sunrise-sunset.org gerichtet. Die Syntax enthält die Koordinaten des gewünschten Ortes. Geben Sie z.B. in Ihrem Browser folgendes ein:

https://api.sunrise-sunset.org/json?lat=49.7222222&lng=12.1608333&date=today ,

dann erhalten Sie diese Rückmeldung:



Enthalten sind die Sonnenauf- und Sonnenuntergangszeit im UTC-Format. Die werden jetzt in den Zeilen 48 bis 60 bearbeitet und als Variable 'hourrise' und 'hourset' in ganzen Stunden bereitgestellt. Im oben gezeigten Fall würde die Beleuchtung um 4 Uhr aus und um 19 Uhr eingeschaltet.

  
  
44  JSON_URL = "https://api.sunrise-sunset.org/json?lat=49.7222222&lng=12.1608333&date=today"
45  pool = socketpool.SocketPool(wifi.radio)
46  requests = adafruit_requests.Session(pool, ssl.create_default_context())
47  #print("Json abrufen und analysieren von", JSON_URL)
48  response = requests.get(JSON_URL)
49  sunrise = response.json()['results']['sunrise']
50  sunset = response.json()['results']['sunset']
51  if len(sunrise) == 10:
52      sunrise = sunrise[0:1]
53  else:
54      sunrise = sunrise[0:2]
55  hourrise = int(sunrise) + 1
56  if len(sunset) == 10:
57      sunset = sunset[0:1]
58  else:
59      sunset = sunset[0:2]
60  hourset = int(sunset) + 13
61
  

Die Zeilen 62 bis 104 definieren die Relais 1 bis 4, Umschalter für automatischen bzw. manuellen Betrieb und eine Reihe von Variablen sowie den http-Server (103, 104). Für die Umschalter 'auto1' bis 'auto4' wurden die GPIO's 2 bis 5 verwendet, um später den Zustand durch (jetzt noch nicht vorhandene) LED's anzuzeigen.

  
  
62  #  Relais setup
63  relais1 = DigitalInOut(board.GP18)
64  relais1.direction = Direction.OUTPUT
65  relais1.value = False
66  relais2 = DigitalInOut(board.GP19)
67  relais2.direction = Direction.OUTPUT
68  relais2.value = False
69  relais3 = DigitalInOut(board.GP20)
70  relais3.direction = Direction.OUTPUT
71  relais3.value = False
72  relais4 = DigitalInOut(board.GP21)
73  relais4.direction = Direction.OUTPUT
74  relais4.value = False
75
76  #  Umschalter automatisch / manuell
77  auto1 = DigitalInOut(board.GP2)
78  auto1.direction = Direction.OUTPUT
79  auto1.value = True
80  auto2 = DigitalInOut(board.GP3)
81  auto2.direction = Direction.OUTPUT
82  auto2.value = True
83  auto3 = DigitalInOut(board.GP4)
84  auto3.direction = Direction.OUTPUT
85  auto3.value = True
86  auto4 = DigitalInOut(board.GP5)
87  auto4.direction = Direction.OUTPUT
88  auto4.value = True
89
90  r1_color = "#33ff33"
91  r1_show = "anschalten"
92  relais1_state = "aus"
93  r2_color = "#33ff33"
94  r2_show = "anschalten\nwenn dunkel"
95  relais2_state = "aus"
96  r3_color = "#33ff33"
97  r3_show = "anschalten"
98  relais3_state = "aus"
99  r4_color = "#33ff33"
100 r4_show = "keine\nBewegung"
101 relais4_state = "aus"
102
103 pool = get_radio_socketpool(wifi.radio)
104 server = Server(pool, "/static", debug=True)
105

Es folgt ab Zeile 106 die Funktion, welche die Webseite im Browser darstellt. Dazu werden 12 Variable übergeben, die zur Beschriftung der Button und Zustandsanzeige dienen. Markieren Sie den kompletten Inhalt der unteren Textbox und kopieren ihn ab Zeile 106 in Ihre Thonny IDE. Damit umfasst das bisherige Programm die Zeilen 1 bis 144. Ggf. fügen Sie als Zeile 145 noch eine Leerzeile ein.




Als nächstes wird der Webserver aufgerufen. In dieser Funktion werden zunächst die Zeit bestimmt und die Sensoren gelesen (Zeilen 148-155). Danach folgen die Bereiche für den Lüfter (Zeilen 159-183), den Dämmerungsschalter (Zeilen 184-208), die Schaltung nach Sonnenauf- und Sonnenuntergang (Zeilen 209-231) und der Bereich für den Bewegungsmelder (Zeilen 232-256). In Zeile 260 wird die Antwort auf die Anfrage zurückgegeben. Machen Sie sich keine Sorgen. Im unteren Kasten ist aus Platzgründen nur ein Teil angezeigt. Beim Übertragen in die Thonny-IDE in diesem und im nächsten Kasten wird aber selbstverständlich alles kopiert.

  
  
146 @server.route("/")
147 def base(request: Request):
148    current_time = time.localtime()
149    hour = current_time.tm_hour
150    # Temperatur : auslesen
151     temp = bme280.temperature
152    # Lichtsensor: auslesen des ADC
153    value = ADC_2.value
154    # pir-Sensor: auslesen
155    pir_value = pir.value
...
...
...
257     ###
258     #  Serve the web page
259     ###
260     return Response(request, f"{webpage(r1_color, r1_show, relais1_state, r2_color, r2_show, relais2_state, r3_color, r3_show, relais3_state, r4_color, r4_show, relais4_state)}", content_type='text/html')
261

Wenn Sie zur Probe eine Zeile 262 mit folgenden Aufruf eingeben:
server.serve_forever(str(wifi.radio.ipv4_address)), können Sie testen, ob der Server funktioniert.


Der Browser sollte ihn dann wie im Bild anzeigen. Bisher reagieren aber die Button noch nicht! Wichtig ist, dass keine Fehlermeldung erscheint, denn dann sind Sie dem Ziel schon ganz nah. Es fehlt jetzt nur noch eine Funktion, welche die Webseite nach der Betätigung eines Button neu lädt und die geänderten Funktionen auf den Button anzeigt. Dazu löschen Sie die Zeile 262 vom gerade durchgeführten Test wieder. Kopieren Sie nun den Quellcode aus dem unteren Kasten und setzen ihn in die Thonny-IDE ab Zeile 262 ein.

  
  
262 #  if a button is pressed on the site
263 @server.route("/", POST)
264 def buttonpress(request: Request):
265     #  get the raw text
...
...
...
363         if relais4.value == True:
364             r4_color = "#ff3333"
365             r4_show = "manuell\nausschalten"
366             relais4_state = "an"
367
368     return Response(request, f"{webpage(r1_color, r1_show, relais1_state, r2_color, r2_show, relais2_state, r3_color, r3_show, relais3_state, r4_color, r4_show, relais4_state)}", content_type='text/html')
369
370 server.serve_forever(str(wifi.radio.ipv4_address))

Geschafft. Sie können jetzt den Webserver starten, indem Sie im Thonny auf 'Ausführen' klicken. In der Kommandozeile erscheint dann z.B.:
Started development server on http://192.169.181.77:5000
Die angezeigte IP-Adresse aus Ihrem Netzwerk wurde dem Server per DHCP von Ihrem Router zugewiesen. Klicken Sie darauf und es öffnet sich der Browser mit dem Server. Wenn Sie den Server vom Smartphone aus steuern wollen, welches sich natürlich im WLAN-Netz befinden muss, brauchen Sie dort ebenfalls nur die IP-Adresse eingeben.



Viel Spass und Erfolg beim Ausprobieren.