MicroPython Daten per VPN senden

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Abend zusammen,

ich stehe leider mal wieder vor einem Problem.

Ich habe/hatte einen Pi Zero, der hat eine zeitlang einen Sensor ausgelesen, die Daten in eine Datenbank geschrieben. Auf dem Raspi lief Apache2 das mir eine selbst erstelle Webseite mit den Sensorwerten auslieferte. Da ich die Webseite nicht nur lokal erreichen wollte, habe ich einen V-Server gemietet. Per WireGuard war der Raspi mit dem V-Server verbunden und ich konnte über die IP des Servers meine Webseite aus dem Internet aufrufen. Das hat wunderbar funktioniert, ist aber gerade nicht mehr in Gebrauch.

Jetzt habe ich einen neuen Anwendungsfall, der eigentlich mehr oder weniger die gleichen Anforderungen hat. Wir haben Schildkröten und die, man sollte es nicht glauben, wachsen und wachsen vor sich hin. Es wurde also Zeit das Außengehäge zu erweitern, in diesem Zuge haben wir ein Gewächshaus gekauft. Wir wollen jetzt mal die Temperatur in dem Gewächshaus überwachen und beobachten um ein Gefühl dafür zu bekommen welche Bedingungen in dem Gewächshaus herrschen.
Dafür wollte ich den Pi nehmen, jedoch hat der einen Defekt. Kurz einen neuen bestellen ist leider auch nicht, die sind überall ausverkauft und einen gebrauchten für 40€ finde ich schon sehr frech.

Ich habe noch 3 ESP32 hier und überlege nun ob ich einen von denen dafür verwenden könnte.
Die Webseite und die Datenbank könnte ich auch auf dem V-Server einrichten, nur wie bekomme ich die Daten dort hin?
Über das MP-Forum bin ich auf MQTT gestoßen. Aber so wirklich voran gebracht hat mich das auch nicht. Bin ich damit überhaupt auf dem richtigen Weg oder wie würdet ihr die Daten an den Server übertragen?

Serverseitig bin ich auch komplett frei und kann da installieren was benötigt wird.

Vielen Dank euch schon mal.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

MQTT passt schon, das VPN ist nur ein Problem. Man kann aber de. Mosquitto auf dem vserver auch ohne VPN, dafür mit credentials, laufen lassen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Wegen ein paar Temperaturwerten, die kann man einfach per HTTP an den Server übertragen.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Vielen Dank für die schnelle Antworten.

@__deets__:
Du meinst das ich einen User + Passwort anlege und Mosquitto dann so konfiguriere, dass nur der User mt Passwort Daten senden darf?

@Sirius3:
Das ist auch eine interessante Idee. So etwas ähnliches habe ich ja gemacht, als ich bei der Schweissvorrichtung Messdaten vom ESP an meinem Laptop gesendet habe. Da habe ich am ESP einen Acces-Point eröffnet und den Laptop dann damit verbunden. Dann die Daten mit 'socket' per HTTP verschickt.

Dann schaue ich mal, wie weit ich komme und werde die für mich einfachere Variante verwedenen. ☺


Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Dennis: genau das.

MQTT hat gegenüber HTTP den Vorteil für sowas gedacht ist. So kann man zb mit der QOS kontrollieren, wie wichtig einem die Werte sind. Und auch die ganze Kette danach - einfließen lassen in InfluxDB, etc, ist halt schon vorbereitet.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hi,

schön das wir mal nicht aneinander vorbei reden :D

Jetzt komme ich aber alleine nicht weiter.
Ich habe auf dem V-Server Mosquitto installiert und nach dieser Anleitung installiert und eingerichtet.
Ich habe auf 'no-ip.com' ein DNS-Adresse angelegt und auch ein Zertifikat installiert.
Danach habe ich vier Dateien mit folgenden Pfaden:
"/etc/mosquitto/certs/server.pem"
"/etc/ssl/certs/ISRG_Root_X1.pem"
"/etc/mosquitto/certs/server.key"
"/etc/ssl/certs/dhparam.pem"

Dann kann ich auf dem Server mit

Code: Alles auswählen

mosquitto_sub -u <USERNAME> -P <PASSWORD> -t "home/"
auf eine Nachricht warten.
Öffne ich eine zweite SSH Verbindung zum Server und geben ein:

Code: Alles auswählen

mosquitto_pub -h <MEINE_DDNS> -t "home/" -m "hello" -p 8883 --capath /etc/ssl/certs/ -u <USERNAME> -P <PASSWORD>
Dann erhalte ich die Nachricht. Schein für mich ein gutes Zeichen zu sein.

Den Port 8883 habe ich in den Firewallrichtlinien des Servers für TCP/UDP geöffnet.

Jetzt gehts auf den ESP32 mit MicroPython.
Ich habe die Datei 'server.pem' und 'server.key' als Textdatei auf dem ESP32 gespeichert und will eine Verbindung zu meinem V-Server aufbauen.
Da ich mir Anfangs nicht sicher war, ob mein ESP32 eine Internetverbindung hat, habe ich noch eine Funktion eingebaut, die mir die Verbindung bestätigt.

Leider bekomme ich keine Verbindung zum V-Server, sondern erhalte folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "<stdin>", line 37, in <module>
  File "<stdin>", line 32, in main
  File "lib/umqtt/simple2.py", line 67, in connect
  File "lib/umqtt/simple2.py", line 19, in _read
  File "lib/umqtt/simple2.py", line 47, in _sock_timeout
MQTTException: 30
der Code dazu sieht so aus:

Code: Alles auswählen

from lib.umqtt import simple2
import ubinascii
import machine
import socket

def is_connected():
    try:
        connection = socket.socket()
        connection.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
        return True
    except Exception as e:
        print(e)
        return False

def read_cert_data(data_file):
    with open(data_file) as file:
        return file.read()

def main():
    if is_connected():
        key_data = read_cert_data('keyfile.txt')
        cert_data = read_cert_data('certfile.txt')
        connection = simple2.MQTTClient(
            ubinascii.hexlify(machine.unique_id()),
            server=<MEINE_DDNS>,
            user=<USERNAME>,
            password=<PASSWORD>,
            port=8883,
            ssl=True,
            ssl_params={'key': key_data, 'cert': cert_data}
        )
        connection.connect()
        print('verbunden')
    
    
if __name__ == '__main__':
    main()
Die Bibliothek die ich verwende ist auf GitHub hier zu finden. Die habe ich mit 'upip' installiert, deswegen der Ordner 'lib'.

Ich vermute dass das mit den Dateien vielleicht nicht unbedingt die richtige Vorgehensweise ist?
Wäre wirklich nett, wenn ihr mich wieder in die richtige Bahn werft, ich glaub die meisten Leitblanken habe ich schon übersprungen.

Schönen Abend noch und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich habe jetzt noch in 'MQTTClient' das Argument 'socket_timeout' angegeben und zwar als None, also 'socket_timeout=None'.
Wenn ich den Code starte passiert fast eine Minute lang nichts, doch dann wird schließlich "verbunden" ausgegeben.
Immerhin, aber ist die lange Zeit zum verbinden normal? Seltsam finde ich auch, das die 'MQTTException: 30' im Netz fast nicht zu finden ist.

Jetzt muss ich raus finden wie ich in MP einen Wert mit MQTT an den Server sende, um die Funktion mal zu überprüfen.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Den DDNS Teil begreife ich nicht. Ich dachte du hast einen VServer. Was hat DDNS da zu tun? Da kannst du doch echtes DNS benutzen? Und kannst du den MQTT Server come Notebook ohne VPN erreichen? Wenn nicht, dann gehts eh noch nicht mit dem Micro.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Abend und dankeschön.

Ich dachte, dass ich die DDNS wegen des Zertifikats brauche. Aber ich könnte das auch mal mit dem DNS Hostname versuchen, den ich von IONOS für den Server bekommen habe.

Ich habe auf dem Laptop gerade eine Virtuelle Ubuntu Maschine mit Mosquitto und kann mit folgendem Befehl eine Nachricht an den V-Server senden:

Code: Alles auswählen

mosquitto_pub -h <MEINEDDNS> -t "home/" -m "hello" -p 8883 --capath /etc/ssl/certs/ -u <USERNAME> -P <PASSWORD
Sogar auf den ersten Versuch. '--capath' gibt an wo die Zertifikate auf dem V-Server liegen, denn auf meiner virteullen Laptop Maschine habe ich die Zertifikate nicht. Wenn ich die in MP weglasse, erscheint auch das "verbunden". Dann war dieser Schritt wohl unnötig.

Wenn ich aber in MP nach 'connect()'

Code: Alles auswählen

connection.publish(b"home/", b"Hallo")
sende, kommt das im V-Server nicht an obwohl dieser mit folgendem Befehl auf Nachrichten wartet:

Code: Alles auswählen

mosquitto_sub -u <USERNAME> -P <PASSWORD> -t "home/"
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

da ich zeitlich leider etwas eingespannter bin wollte ich das Senden mit HTTP mal versuchen.
Das hat sich eigentlich einfach angehört, aber jetzt ist der Berg vor mir noch viel größer geworden, den ich weis nicht mal wie ich beginnen soll.

Auf meinem V-Server muss wohl ein Python-Programm laufen, dass die Werte entgegen nimmt. Das habe ich mir mal im groben so vorgestellt:

Code: Alles auswählen

#!/usr/bin/env python3
import requests
from time import sleep


def main():
    while True:
        print(requests.get("http://192.168.0.191").json())
        sleep(1)

if __name__ == "__main__":
    main()
Erstes Problem wäre, dass die IP des ESP's die ich da eingetragen habe, ja gar nicht aus dem Internet erreichbar ist.

Auf dem ESP muss ein Code laufen, der sich mit dem V-Server verbindet. Das würde im Ansatz bei mir so aussehen:

Code: Alles auswählen

import socket


def is_connected():
    try:
        connection = socket.socket()
        connection.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
        return True
    except Exception as error:
        print(eroor)
        return False


def main():
    if is_connected():
        try:
            connection = socket.socket()
            connection.connect((<IP-VSERVER>, 80))
            print('verbunden')
        except Exception as error:
            print(error)
            
            
if __name__ == '__main__':
    main()
Der gibt mir ein:

Code: Alles auswählen

[Errno 104] ECONNRESET
aus. Kein Traceback, sondern nur das.

Das wäre das zweite Problem.
Und das dritte Problem, eigentlich das was ich als erstes beheben muss, ist das ich weder in der Doku noch im Netz irgendwelche brauchbaren Infos finde, wie man so eine Verbindung aufbaut.
Gut möglich dass ich es auch aus Verständnisproblemen nicht gefunden habe.

Ich wäre sehr dankbar für ein paar Infos von euch.

Grüße
Dennis

Ich schrieb ja, das ich so was ähnliches schon gemacht habe, da war aber der Laptop der die Daten vom ESP bekam, mit dem Accesspoint verbunden, der den ESP eröffnet hatte. Jetzt ist der ESP aber im privaten Wlan eingebunden und der V-Server steht im Internet.
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich bin davon ausgegangen, dass auf Deinem V-Server bereits ein HTTP-Server läuft, und Du nur noch eine weitere Route implementieren mußt, die den Temperaturwert in eine Datenbank schreibt.
Das was Du ja jetzt versuchst, ist, von außen auf Deinen ESP zuzugreifen, auf dem dann ein HTTP-Server läuft, was ja irgendwie verquer ist.

Code: Alles auswählen

	
import urequests
response = urequests.post("https://dein-v-server/temperatur", data=temperatur)
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Danke für die Antwort.
Apache2 läuft auf dem Server, eine Datenbank aber noch nicht. Wenn ich eine Datenbank installiere, dann muss ich mich vom ESP mit der Datenbank verbinden?

Dein Code läuft ohne Fehlermeldung durch, aber es passiert auf dem Server auch nichts. Ich habe eine leere Datei erstellt '/var/www/html/temperatur' und in deinem Code einfach den String 'temperatur' verschickt. Die Datei blieb aber leer.
Muss ich mit socket den 'response' noch verschicken?
Mit 'print(response' erhalte ich nur:

Code: Alles auswählen

<Response object at 3ffe6140>
Also so:

Code: Alles auswählen

import socket
import urequests

def is_connected():
    try:
        connection = socket.socket()
        connection.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
        return True
    except Exception as error:
        print(eroor)
        return False


def main():
    if is_connected():
        response = urequests.post("VSERVER-ADRESSE/temperatur", data='temperatur')
        print(response)
        print('verbunden')
            
            
if __name__ == '__main__':
    main()
Was muss denn auf der anderen Seite(auf dem Server) auf die Nachricht warten?

Ich steige noch gar nicht durch was da wo gemacht wird und/oder gemacht werden muss. Hier steht das 'post' eine eine post-Anfrage sendet. Das sind mir leider zu wenig Infos um zu verstehen was ich da eigentlich mach/ machen muss.

Grüße und Danke
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Du schickst Daten vom ESP per HTTP an einen auf dem vServer lauschenden HTTP-Server. Bevor du da hart einsteigst und das selbst mit Sockets zusammen bastelst, würde ich ein Framework wie Flask, Falcon oder FastAPI in Kombination mit einem Server wie gunicorn oder uvicorn verwenden. Der wartet auf den POST-Request deines ESP, nimmt die Daten und verarbeitet sie (z. B. schreibt sie in eine Datenbank).
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

danke für die Hinweise. Da ich noch keine Berührpunkte mit den von dir genannten Beispiele hatte, habe ich jeweils das erste auf dem V-Server installiert. Also Flask und Gunicorn.
Wenn ich nach Tutorials oder ähnliches suche, stolpere ich immer über Seiten die mir sagen das ich noch nginx brauche. Ich dachte Gunicorn sei schon der Server. Wirklich Fuß fassen konnte ich damit noch gar nicht.
Wenn man nach FastAPI und Unvicorn sucht stoßt man auf das Tutorial:
https://realpython.com/fastapi-python-web-apis/

Das sieht für mich mal nach einem Ansatz aus und werde ich mir gegen später mal vornehmen (falls nichts dagegen spricht?).
Jetzt muss ich erst mal den Kopf frei bekommen. Das Netzwerkzeugs bringt mich immer wieder zum verzweifeln und im Vergleich zu den Problemen, bei denen man mir hier sonst so geholfen hat, macht mir das vieeel weniger Spass.

Ich melde mich wieder und vielen Dank euch noch mal für die Unterstützung!

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ein Stückchen bin ich weiter gekommen. Habe FastAPI und Uvicorn auf dem VServer und das Tutorial durchgearbeitet bzw. ich bin dabei.
Hier wird nur beschrieben wie ich mit http und der lokalen IP die Testwebseite aufrufen kann.
Wenn ich jetzt aber die Seite über die DNS-Adresse oder die öffentliche IP aufrufen will, dann kann ich das zwar mit der Option '--host' angeben, aber das ist immer noch http und ich erhalte im Browser eine Meldung, dass der Server zu lange zum antworten braucht.

Ich kann zwar auch angeben wo die SSL-Zertifikate liegen, aber dafür braucht Uvicorn eine Passwort-file von den Zertifikaten und so wie ich das recherchiert habe, läuft das mit den privaten Zertifikaten nur, wenn ich noch nginx vorschalte.
Seht ihr eine Möglichkeit, wie ich jetzt aus dem Internet die Testwebseite aufrufen kann?
Die Optionen die ich angeben kann:

Code: Alles auswählen

(fastapi) spike@localhost:~/fastapi_test$ uvicorn --help
Usage: uvicorn [OPTIONS] APP

Options:
  --host TEXT                     Bind socket to this host.  [default:
                                  127.0.0.1]
  --port INTEGER                  Bind socket to this port.  [default: 8000]
  --uds TEXT                      Bind to a UNIX domain socket.
  --fd INTEGER                    Bind to socket from this file descriptor.
  --reload                        Enable auto-reload.
  --reload-dir PATH               Set reload directories explicitly, instead
                                  of using the current working directory.
  --reload-include TEXT           Set glob patterns to include while watching
                                  for files. Includes '*.py' by default; these
                                  defaults can be overridden with `--reload-
                                  exclude`. This option has no effect unless
                                  watchfiles is installed.
  --reload-exclude TEXT           Set glob patterns to exclude while watching
                                  for files. Includes '.*, .py[cod], .sw.*,
                                  ~*' by default; these defaults can be
                                  overridden with `--reload-include`. This
                                  option has no effect unless watchfiles is
                                  installed.
  --reload-delay FLOAT            Delay between previous and next check if
                                  application needs to be. Defaults to 0.25s.
                                  [default: 0.25]
  --workers INTEGER               Number of worker processes. Defaults to the
                                  $WEB_CONCURRENCY environment variable if
                                  available, or 1. Not valid with --reload.
  --loop [auto|asyncio|uvloop]    Event loop implementation.  [default: auto]
  --http [auto|h11|httptools]     HTTP protocol implementation.  [default:
                                  auto]
  --ws [auto|none|websockets|wsproto]
                                  WebSocket protocol implementation.
                                  [default: auto]
  --ws-max-size INTEGER           WebSocket max size message in bytes
                                  [default: 16777216]
  --ws-ping-interval FLOAT        WebSocket ping interval  [default: 20.0]
  --ws-ping-timeout FLOAT         WebSocket ping timeout  [default: 20.0]
  --ws-per-message-deflate BOOLEAN
                                  WebSocket per-message-deflate compression
                                  [default: True]
  --lifespan [auto|on|off]        Lifespan implementation.  [default: auto]
  --interface [auto|asgi3|asgi2|wsgi]
                                  Select ASGI3, ASGI2, or WSGI as the
                                  application interface.  [default: auto]
  --env-file PATH                 Environment configuration file.
  --log-config PATH               Logging configuration file. Supported
                                  formats: .ini, .json, .yaml.
  --log-level [critical|error|warning|info|debug|trace]
                                  Log level. [default: info]
  --access-log / --no-access-log  Enable/Disable access log.
  --use-colors / --no-use-colors  Enable/Disable colorized logging.
  --proxy-headers / --no-proxy-headers
                                  Enable/Disable X-Forwarded-Proto,
                                  X-Forwarded-For, X-Forwarded-Port to
                                  populate remote address info.
  --server-header / --no-server-header
                                  Enable/Disable default Server header.
  --date-header / --no-date-header
                                  Enable/Disable default Date header.
  --forwarded-allow-ips TEXT      Comma separated list of IPs to trust with
                                  proxy headers. Defaults to the
                                  $FORWARDED_ALLOW_IPS environment variable if
                                  available, or '127.0.0.1'.
  --root-path TEXT                Set the ASGI 'root_path' for applications
                                  submounted below a given URL path.
  --limit-concurrency INTEGER     Maximum number of concurrent connections or
                                  tasks to allow, before issuing HTTP 503
                                  responses.
  --backlog INTEGER               Maximum number of connections to hold in
                                  backlog
  --limit-max-requests INTEGER    Maximum number of requests to service before
                                  terminating the process.
  --timeout-keep-alive INTEGER    Close Keep-Alive connections if no new data
                                  is received within this timeout.  [default:
                                  5]
  --ssl-keyfile TEXT              SSL key file
  --ssl-certfile TEXT             SSL certificate file
  --ssl-keyfile-password TEXT     SSL keyfile password
  --ssl-version INTEGER           SSL version to use (see stdlib ssl module's)
                                  [default: 17]
  --ssl-cert-reqs INTEGER         Whether client certificate is required (see
                                  stdlib ssl module's)  [default: 0]
  --ssl-ca-certs TEXT             CA certificates file
  --ssl-ciphers TEXT              Ciphers to use (see stdlib ssl module's)
                                  [default: TLSv1]
  --header TEXT                   Specify custom default HTTP response headers
                                  as a Name:Value pair
  --version                       Display the uvicorn version and exit.
  --app-dir TEXT                  Look for APP in the specified directory, by
                                  adding this to the PYTHONPATH. Defaults to
                                  the current working directory.  [default: .]
  --h11-max-incomplete-event-size INTEGER
                                  For h11, the maximum number of bytes to
                                  buffer of an incomplete event.
  --factory                       Treat APP as an application factory, i.e. a
                                  () -> <ASGI app> callable.
  --help                          Show this message and exit.
Und der Bespielcode aus dem Tutorial:

Code: Alles auswählen

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}
Dann starte ich den Server zum Beispiel mit:

Code: Alles auswählen

(fastapi) spike@localhost:~/fastapi_test$ uvicorn main:app --reload --host <Server IP>
INFO:     Will watch for changes in these directories: ['/home/spike/fastapi_test']
INFO:     Uvicorn running on http://<Server IP>:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [22317] using WatchFiles
INFO:     Started server process [22320]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

Aber wenn ich im Browser "http://<Server IP>:8000" eingebe erhalte ich:
Fehler: Netzwerk-Zeitüberschreitung

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
paddie
User
Beiträge: 101
Registriert: Donnerstag 11. Oktober 2018, 18:09

Dennis89 hat geschrieben: Donnerstag 6. Oktober 2022, 14:18 Danke für die Antwort.
Apache2 läuft auf dem Server, eine Datenbank aber noch nicht. Wenn ich eine Datenbank installiere, dann muss ich mich vom ESP mit der Datenbank verbinden?
Bloß nicht!!1elf :shock:. Die Datenbank sollte auf keinen Fall direkt von außen erreichbar sein. Der Zugriff darauf sollte nur über deine Anwendung oder den MQTT auf dem vServer erfolgen.
paddie
User
Beiträge: 101
Registriert: Donnerstag 11. Oktober 2018, 18:09

Dennis89 hat geschrieben: Donnerstag 6. Oktober 2022, 21:45 Hallo,

ein Stückchen bin ich weiter gekommen. Habe FastAPI und Uvicorn auf dem VServer und das Tutorial durchgearbeitet bzw. ich bin dabei.
Hier wird nur beschrieben wie ich mit http und der lokalen IP die Testwebseite aufrufen kann.
Wenn ich jetzt aber die Seite über die DNS-Adresse oder die öffentliche IP aufrufen will, dann kann ich das zwar mit der Option '--host' angeben, aber das ist immer noch http und ich erhalte im Browser eine Meldung, dass der Server zu lange zum antworten braucht.

Ich kann zwar auch angeben wo die SSL-Zertifikate liegen, aber dafür braucht Uvicorn eine Passwort-file von den Zertifikaten und so wie ich das recherchiert habe, läuft das mit den privaten Zertifikaten nur, wenn ich noch nginx vorschalte.
Seht ihr eine Möglichkeit, wie ich jetzt aus dem Internet die Testwebseite aufrufen kann?
Normalerweise kann man beim Erstellen der SSL-Zertifikate ein Passwort eingeben, wenn man dieses eingibt muß man es dann natürlich auch irgendwo hinterlegen :geek:. Bei Zertifikaten für Domains wird das aber eigentlich nie gemacht (ich habs zumindest noch nie erlebt). Also erstell einfach die Zertifikate nochmal neu OHNE das Passwort. Dann sollte er nicht mehr nach dem Password-File fragen.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo und danke für die Antwort.

Beim erstellen habe ich kein Passwort eingegeben.

Manchmal braucht man einfach mal etwas Abstand. Heute morgen fiel mir ein, dass ich den Port 8000 in den Firewalleinstellungen natürlich freigeben muss. Entschuldigt das ich euch hier wegen so einem doofen Fehler verrückt gemacht habe.
Stand der Dinge ist, das ich jetzt mit http://<SERVERIP>:8000 auf den FastAPI Server zugreifen kann und es wird mir mein "Hello World" angezeigt.

Wenn ich jetzt auf dem ESP folgendes ausführe:

Code: Alles auswählen

import socket
import urequests

def is_connected():
    try:
        connection = socket.socket()
        connection.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
        return True
    except Exception as error:
        print(eroor)
        return False


def main():
    if is_connected():
        response = urequests.post("http://217.160.51.17:8000", data='temperatur')
        print(response)
        print('verbunden')
            
            
if __name__ == '__main__':
    main()
Dann erscheint im Serverterminal folgendes:

Code: Alles auswählen

(fastapi) spike@localhost:~/fastapi_test$ uvicorn main:app --reload --host <SERVER IP>
INFO:     Will watch for changes in these directories: ['/home/spike/fastapi_test']
INFO:     Uvicorn running on http://<SERVER IP>:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [24201] using WatchFiles
INFO:     Started server process [24204]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     78.43.40.238:41282 - "GET / HTTP/1.1" 200 OK
INFO:     78.43.40.238:49041 - "GET / HTTP/1.1" 200 OK
WARNING:  Invalid HTTP request received.
INFO:     78.43.40.238:49062 - "POST / HTTP/1.0" 405 Method Not Allowed
INFO:     78.43.40.238:49030 - "GET / HTTP/1.1" 200 OK
INFO:     78.43.40.238:49041 - "POST / HTTP/1.0" 405 Method Not Allowed
"Method Not Allowed" ist zwei mal drin, weil ich den Code auf dem ESP zwei mal ausgeführt habe.

Muss ich irgendwie noch mitteilen, wer Daten senden darf?

Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Du hast im FastAPI-Code @app.get("/") geschrieben. Damit erlaubst du nur GET-Requests. Wenn du POST-Requests auf diese Route zulassen willst, musst du @app.post("/") verwenden.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist ja wunderbar, dass Dein ESP mit dem V-Server kommunizieren kann.
Jetzt mußt Du natürlich noch mit FastAPI den Code schreiben, der die Temperaturwerte weiter verarbeitet.
Antworten