projekt:python_fastapi
Dies ist eine alte Version des Dokuments!
Inhaltsverzeichnis
GPIO mit FastAPI (Websteuerung)
0. ENV (VENV)
source ~/devel/projects/course_env/bin/activate pip install fastapi uvicorn RPi.GPIO which uvicorn
Erwartet:
/home/pi/devel/projects/course_env/bin/uvicorn
1. PROJEKTORDNER
cd /home/pi/devel/projects mkdir -p python_web/src/core cd python_web/src/core touch __init__.py
2. HARDWARE (LED + DS18B20)
Datei:
/home/pi/devel/projects/python_web/src/core/hardware.py
import RPi.GPIO as GPIO import glob import time # ----------------------------- # API-Funktionen GPIO LED Ampel # ----------------------------- PIN_R = 17 PIN_Y = 27 PIN_G = 22 _initialized = False def init(): global _initialized if _initialized: return GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(PIN_R, GPIO.OUT) GPIO.setup(PIN_Y, GPIO.OUT) GPIO.setup(PIN_G, GPIO.OUT) _initialized = True def setLED(pin, value): if value == 1: GPIO.output(pin, GPIO.HIGH) else: GPIO.output(pin, GPIO.LOW) def setRedLED(value): setLED(PIN_R, value) def setYellowLED(value): setLED(PIN_Y, value) def setGreenLED(value): setLED(PIN_G, value) def status(): r = GPIO.input(PIN_R) y = GPIO.input(PIN_Y) g = GPIO.input(PIN_G) return r, y, g def cleanup(): GPIO.cleanup() # ----------------------------- # API-Funktionen ds18b20 # ----------------------------- SENSOR_TIMEOUT = 1 # Sekunden def is_sensor(): sensors = glob.glob("/sys/bus/w1/devices/28-*") return len(sensors) > 0 def get_sensor(): sensors = glob.glob("/sys/bus/w1/devices/28-*") if not sensors: return None return sensors[0] + "/w1_slave" def get_temperature(): sensor_file = get_sensor() if sensor_file is None: return None start_time = time.time() while True: with open(sensor_file, "r") as f: lines = f.readlines() if lines[0].strip().endswith("YES"): break if time.time() - start_time > SENSOR_TIMEOUT: return None time.sleep(0.1) temp_line = lines[1] temp_str = temp_line.split("t=")[1] return float(temp_str) / 1000.0
3. FASTAPI APP
Datei:
/home/pi/devel/projects/python_web/src/app.py
from fastapi import FastAPI, HTTPException from fastapi.responses import HTMLResponse, RedirectResponse from core import hardware app = FastAPI() @app.on_event("startup") def startup(): hardware.init() @app.get("/led", response_class=HTMLResponse) def led_page(): r, y, g = hardware.status() return HTMLResponse(f""" <!DOCTYPE html> <html> <head><title>LED Ampel</title></head> <body> <h1>LED Ampel</h1> <h2>Rot (Status: {r})</h2> <a href="/led/r/1">ON</a> <a href="/led/r/0">OFF</a> <h2>Gelb (Status: {y})</h2> <a href="/led/y/1">ON</a> <a href="/led/y/0">OFF</a> <h2>Grün (Status: {g})</h2> <a href="/led/g/1">ON</a> <a href="/led/g/0">OFF</a> <br><br> <a href="/">Zurück</a> </body> </html> """) @app.get("/led/{color}/{value}") def set_led(color: str, value: int): if value not in (0, 1): raise HTTPException(status_code=400) if color == "r": hardware.setRedLED(value) elif color == "y": hardware.setYellowLED(value) elif color == "g": hardware.setGreenLED(value) else: raise HTTPException(status_code=400) return RedirectResponse(url="/led", status_code=303) @app.get("/temp", response_class=HTMLResponse) def temp_page(): t = hardware.get_temperature() if t is None: value = "Sensorfehler" else: value = f"{t:.2f} °C" return HTMLResponse(f""" <!DOCTYPE html> <html> <head><title>Temperatur</title></head> <body> <h1>Temperatur</h1> <p>{value}</p> <br> <a href="/">Zurück</a> </body> </html> """)
4. APACHE STARTSEITE
Datei:
/var/www/html/index.html
<!DOCTYPE html> <html> <head> <title>Projekt Auswahl</title> </head> <body> <h1>Projekt Auswahl</h1> <ul> <li><a href="/wiki">DokuWiki</a></li> <li><a href="/led">LED Ampel</a></li> <li><a href="/temp">Temperatur</a></li> </ul> </body> </html>
5. APACHE PROXY
Datei:
/etc/apache2/sites-available/000-default.conf
Innerhalb von <VirtualHost *:80>:
ProxyPreserveHost On ProxyPass /led http://127.0.0.1:8000/led ProxyPassReverse /led http://127.0.0.1:8000/led ProxyPass /temp http://127.0.0.1:8000/temp ProxyPassReverse /temp http://127.0.0.1:8000/temp
Module aktivieren und Apache neu laden:
sudo a2enmod proxy sudo a2enmod proxy_http sudo systemctl reload apache2
6. SYSTEMD (AUTOSTART)
Datei:
/etc/systemd/system/python_web.service
[Unit] Description=Python Web FastAPI After=network-online.target Wants=network-online.target [Service] User=pi WorkingDirectory=/home/pi/devel/projects/python_web/src ExecStart=/home/pi/devel/projects/course_env/bin/uvicorn app:app --host 127.0.0.1 --port 8000 Restart=always [Install] WantedBy=multi-user.target
Aktivieren:
sudo systemctl daemon-reload sudo systemctl enable python_web sudo systemctl start python_web
7. TEST
8. REBOOT TEST
sudo reboot
Nach Neustart erneut prüfen:
projekt/python_fastapi.1771615091.txt.gz · Zuletzt geändert: von torsten.roehl
