Nach langer Suche im Internet bin ich auf Websockets gestoßen. Das müsste doch für eine bidirektionale Schnittstelle zu einem Pythonprogramm genau das Richtige sein, oder ?
Nach langer Suche im Internet bin ich auf Websockets gestoßen. Das müsste doch für eine bidirektionale Schnittstelle zu einem Pythonprogramm genau das Richtige sein, oder ?
Ja das ist so richtig, aber dann wäre es keine Webseteuerung (über Browser) mehr ... leider entzieht sich HTML und PHP (das wäre in deinem Fall wohl die Lösung vermute ich) meinem Fähigkeitsgebiet
Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
nicht.
Es gibt PHP GPIO da kann man direkt mit den GPIOs kommunizieren. Dann kann man sich den Weg über Python sparen.
cYa pig
Ein häufiger Weg den man bei sowas beschreitet, ist in deinem Python (oder egal welche Sprache) Programm, einen Webserver aufzumachen. Das ist in Python ca. 3 Zeilen Code. Dieser Webserver bindet sich z.B. auf Port 80 auf deiner lokalen IP Adresse. Diese kannst du dann mit deinem Browser aufmachen. Dein Browser kommuniziert mit dem Webserver über GET bzw. POST requests. Diese Request kannst du in deinem Programm selber parsen und je nach Request eine andere Aktion ausführen.
Hört sich zwar bisschen kompliziert am Anfang an, ist aber wirklich einfach, wenn man es mal ausprobiert hat. Siehe https://docs.python.org/3/library/http.server.html
Und noch etwas Beispielcode. Jedoch ungetestet. Habe den aus einem bestehenden Projekt ausgebaut...
Code:import sys, time from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import urlparse, parse_qs class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): # GET def do_GET(self): (host,port) = self.client_address testHTTPServer_RequestHandler.clients[host] = time.time() parsed = parse_qs(urlparse(self.path).query).get('text',[''])[0]; message = "Thanks for your message!" # Send response status code self.send_response(200) # Send headers self.send_header('Content-type','text/html') self.end_headers() # Send message back to client # # Write content as utf-8 data self.wfile.write(bytes(message, "utf8")) return def main(): print("starting server") server_address = ('127.0.0.1', 8080) httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) httpd.timeout = 1 while True: time.sleep(0.001) httpd.handle_request() httpd.close() sys.exit(app.exec_()) main()
Danke für die Antworten
Zu Ceos: warum ist es denn dann keine Websteuerung über Browser mehr? Wenn ich im Browser die Webseite des Pis eingebe und dann das Javascript( welches die Tcp Verbindung mit dem Server beginnt) mit einem Button starte, dann steuere ich den Roboter doch über den Browser, oder funktioniert das so nicht? Browser(TCP/Javascript) <=> Server(TCP/Python)
Zum Thema HTML, PHP und auch GPIO:
So wollte ich das auch erst lösen. Doch habe ich herausgefunden, dass PHP nur serverseitig ausgeführt wird. Und das schafft gleich mehrere Probleme, die ich für meine Websteuerung nicht haben möchte.
1. Muss bei jeder Interaktion (Button click) die Webseite komplett neu geladen werden. Das habe ich früher schon mal ausprobiert. Wenn man nur einen festen Aufbau wie eine Lampe hat ist das nicht so schlimm, da diese eh nicht häufig Steuerimpulse bekommt... Da der Robi aber im WLAN ist und recht zügig Befehle empfangen muss funktioniert das nicht so toll wenn ständig die Seite neu geladen wird...
2. Ist keine gute bidirektionale Verbindung möglich, da bei z.B. Button click man nur per PHP entweder ein Pythonscript starten könnte, was dann die Ausgabe von Steuerimpulsen erlaubt, oder man direkt per PHP wie piggituX gesagt hat die GPIOs ansteuern könnte.
3. Möchte ich nicht die GPIOs normal nutzen, sodern möchte z.B. über I2C Motoren steuern oder Kommunikation mit anderen Dingen durchführen. Dies klappt aber nur, wenn das Script in einer Schleife laufen kann und nicht für jeden Vorgang neu gestartet werden muss...
4. Über PHP lassen sich von einem Pythonscript keine Informationen an die Webseite schicken... (jedenfalls wenn die Bedingung 3. erfüllt sein soll)
Das was shedepe beschreibt, hört sich doch schon mal gut an. Werde ich auf jeden Fall drüber nachdenken. Momentan habe ich das nämlich noch nicht durchblickt... Einen Nachteil sehe ich dabei aber. Es würde nicht mehr so einfach sein mehrere Webseiten mit unterschiedlichen Dingen zu basteln. Die Webseiten brauchen ja auch noch CSS und so...
Ich möchte erst mal noch ein bisschen probieren, ob ich die TCP Lösung hinbekomme, wenn nicht, dann komme ich auf diesen Ansatz zurück.
Der Tcp Ansatz müsste mir doch eigentlich noch einen Vorteil bringen...Theoretisch kann man doch auch die Serverseite mit dem Python Code auf einen anderen PC auslagern??
Probiere gerade die Lösung aus: http://stackoverflow.com/questions/1...-communication
Ich verwende gerade die Lösung Html5 socket von Antwort 1 aus dem Link für mein Javascript im Browser und für das Pythonscript(auf meinem PC, nicht auf PI!!):
Wenn ich das Javascript von Microsoft Edge aus ausführe passiert nichts, wenn ich die Seite aber von Chrome aus verwende gibt mir mein Pythonscript das aus:Code:import socketserver class ChatRequestHandler(socketserver.BaseRequestHandler): def handle(self): addr = self.client_address[0] print("[{}] Verbindung hergestellt".format(addr)) while True: s = self.request.recv(1024) if s: print("[{}] {}".format(addr, s.decode())) else: print("[{}] Verbindung geschlossen".format(addr)) break server = socketserver.TCPServer(("", 50000), ChatRequestHandler) server.serve_forever()
Leider schaffe ich es noch nicht Nachrichten zu senden oder zu empfangen...
Wenigstens verbindet sich da was. Darauf lässt sich ja aufbauen...
Ich verstehe nur noch nicht, wie das mit dem Handshake dings weiter unten im Link funktioniert??
wait what? custom websockets mit javascript im browser? okay man lernt nie aus XD
Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
nicht.
hab ne ganz interessante Webseite dazu gefunden: http://enterprisewebbook.com/ch8_websockets.html
Ich muss also, bevor ich die Kommunikation beginnen kann erst mal einen Schlüssel bearbeiten und dann zurückschicken...
Mein Programm um das zu testen sieht momentan so aus:
Leider bekomme ich nicht den gleichen Accept Schlüssel zum zurückschicken raus wie im Beispiel auf der Seite...Code:import hashlib import base64 MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" HSHAKE_RESP = "HTTP/1.1 101 Switching Protocols\r\n" + \ "Upgrade: websocket\r\n" + \ "Connection: Upgrade\r\n" + \ "Sec-WebSocket-Accept: %s\r\n" + \ "\r\n" data = "GET HTTP/1.1\r\n" + \ "Upgrade: websocket\r\n" + \ "Connection: Upgrade\r\n" + \ "Host: echo.websocket.org\r\n" + \ "Origin: http://www.websocket.org\r\n" + \ "Sec-WebSocket-Key: i9ri`AfOgSsKwUlmLjIkGA==\r\n" + \ "Sec-WebSocket-Version: 13\r\n" + \ "Sec-WebSocket-Protocol: chat\r\n" print("HSHAKE_RESP: ", HSHAKE_RESP) print("data: ", data) headers = {} lines = data.splitlines() for l in lines: parts = l.split(": ", 1) if len(parts) == 2: headers[parts[0]] = parts[1] headers['code'] = lines[len(lines) - 1] key = headers['Sec-WebSocket-Key'] print("key: ", key) combi = key + MAGIC; combi_b = combi.encode('UTF-8') print("combi: ", combi) #print("combi_b: ", combi_b) resp_data = HSHAKE_RESP % ((base64.b64encode(hashlib.sha1(combi_b).digest()),)) print("resp_data: ", resp_data)
Die schicken den Key: i9ri`AfOgSsKwUlmLjIkGA== an das Serverscript und bekommen dann, wenn sie es mit dem "special globally unique identifier (GUID) string 258EAFA5-E914-47DA-95CA-C5AB0DC85B11" bearbeitet haben das raus: Qz9Mp4/YtIjPccdpbvFEm17G8bs=
Ich bekomme aber das raus: ti16O6oiN0nzWbVtqq9omKeAd/Y=
warum ? Kann mir einer helfen ? Ich habe ja schließlich nichts groß verändert, sondern den Code fast von da ganz unten übernommen : http://stackoverflow.com/questions/1...ing-to-python#
Lesezeichen