Seite 1 von 1

Websocket

Verfasst: Mittwoch 12. April 2023, 07:11
von pascal.buehler
Hallo zusammen ich habe da ein Problem mit dem zugriff auf einen Websocket. Mit dem MQTT Browser kann ich über ws direkt auf den Server zugreifen. jedoch mit python geht es nicht, ich glaube es liegt an der Autehtifikation. Wenn ich das ping pong mache, sehe ich per wireshark, dass ein pong an die adresse gemacht wird, jedoch kommt bei mir None. habe einige variationen getestet, aber nicht geht. Weiss jemand weiter oder ein guter Rat?


# Pakete importieren
import websocket
import ssl
import json
import time
import numpy as np
import csv
import matplotlib.pyplot as plt

# Allgemeine Einstellungen
path = ["C:\\Users\\buehlpas\\Desktop\\Messungen\\"]
name = ["Smart_Sensor_WS"]
ending = [".csv", ".svg"]
datum = time.localtime()
format('%4d')
# Definition Variablen
m = 1 # Anzahl Messdurchlauf
n = 10 # Anzahl Messpunkte
t0 = time.time()
t = []
u = []
v = []
w = []
z = []
header = ["Time t [s]", "MQTT Topic [num]", "MQTT Payload [num]"]
body = []
topics = [("sauter/ecos504/411001065754/status/analog-value/1/present-value", 0),
("sauter/ecos504/411001065754/status/analog-value/2/present-value", 0)]
active = True


# The callback for when the client is connected to the server.
def on_connect(ws):
print("Connection opened")


# The callback for when the client is disconnected to the server.
def on_close():
print("Connection closed")


# The callback for when the client has an error to the server.
def on_error(ws, error):
print(error)


# The callback for when a message is received from the server.
def on_receive(ws, msg):
global t
global active
print("Received message '" + str(msg.payload.decode("utf-8")) + "' on topic '"
+ msg.topic + "' with QoS " + str(msg.qos) + "' Count " + str(len(u)))
t.append(str(time.time() - t0))
# u.append(str(msg.topic).split("/")[5])
# v.append(str(msg.payload.decode("utf-8")))
# body.append([t[-1], u[-1], v[-1]])

if len(t) > n:
active = False


# The callback for when a message is published from the server.
def on_send(ws, payload):
print("Message Sent...")


def on_pong(ws, message):
print("Got a pong! No need to respond")


# Callback Function
websocket.enableTrace(True)
ws = websocket.WebSocket()
# ws.connect = on_connect
ws.close = on_close
ws.error = on_error
# ws.recv = on_receive
# ws.send = on_send
ws.pong = on_pong

# WS Definition
host = "192.168.10.70"
port = "9001"
username = 'admin'
password = 'sauter'

# connect to broker
ws.connect("ws://admin:sauter@192.168.10.70:9001", origin="192.168.10.11", subprotocols=["mqtt"])
print(ws.getheaders())
print(ws.getstatus())
print(ws.getsubprotocol())
print(ws.ping("This is an optional ping payload"))

# ws.send("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/analog-value/1/present-value", "10.00")
# wsapp = websocket.WebSocketApp("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/", on_message=on_message)

# Start the loop
# wsapp.run_forever(http_proxy_host=host, http_proxy_port=port, http_proxy_auth=(username, password))
# Smart Sensor datas

# Loop Bedingung
# while active:
# time.sleep(1)
# Bedingung Erfüllt Loop wird gestoppt
# wsapp.on_close
# Messung Ende, Schnittstelle freigeben
ws.close()

Re: Websocket

Verfasst: Mittwoch 12. April 2023, 09:19
von grubenfox
wie lautet denn die Fehlermeldung?
ps: die komplette Fehlermeldung mit Stacktrace

Re: Websocket

Verfasst: Mittwoch 12. April 2023, 09:24
von pascal.buehler
Backend TkAgg is interactive backend. Turning interactive mode on.
--- request header ---
DEBUG:websocket:--- request header ---
GET / HTTP/1.1
Upgrade: websocket
Host: 192.168.10.70:9001
Origin: 192.168.10.11
Sec-WebSocket-Key: o70eACx/Gh01pS4Ns1i+Cg==
Sec-WebSocket-Version: 13
Connection: Upgrade
Sec-WebSocket-Protocol: mqtt
DEBUG:websocket:GET / HTTP/1.1
Upgrade: websocket
Host: 192.168.10.70:9001
Origin: 192.168.10.11
Sec-WebSocket-Key: o70eACx/Gh01pS4Ns1i+Cg==
Sec-WebSocket-Version: 13
Connection: Upgrade
Sec-WebSocket-Protocol: mqtt
-----------------------
DEBUG:websocket:-----------------------
--- response header ---
DEBUG:websocket:--- response header ---
HTTP/1.1 101 Switching Protocols
DEBUG:websocket:HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
DEBUG:websocket:Upgrade: WebSocket
Connection: Upgrade
DEBUG:websocket:Connection: Upgrade
Sec-WebSocket-Accept: /2l6XoqBsTPkt6vc5H1TAHpm1vo=
DEBUG:websocket:Sec-WebSocket-Accept: /2l6XoqBsTPkt6vc5H1TAHpm1vo=
Sec-WebSocket-Protocol: mqtt
DEBUG:websocket:Sec-WebSocket-Protocol: mqtt
-----------------------
DEBUG:websocket:-----------------------
++Sent raw: b'\x89\xa0 \x87]\x03t\xef4p\x00\xee.#A\xe9}lP\xf34lN\xe61#P\xee3d\x00\xf7<zL\xe8<g'
DEBUG:websocket:++Sent raw: b'\x89\xa0 \x87]\x03t\xef4p\x00\xee.#A\xe9}lP\xf34lN\xe61#P\xee3d\x00\xf7<zL\xe8<g'
++Sent decoded: fin=1 opcode=9 data=b'This is an optional ping payload'
DEBUG:websocket:++Sent decoded: fin=1 opcode=9 data=b'This is an optional ping payload'
{'upgrade': 'WebSocket', 'connection': 'Upgrade', 'sec-websocket-accept': '/2l6XoqBsTPkt6vc5H1TAHpm1vo=', 'sec-websocket-protocol': 'mqtt'}
101
mqtt
None
Connection closed

Re: Websocket

Verfasst: Mittwoch 12. April 2023, 09:47
von __deets__
Code und Fehlermeldungen bitte in die dafuer vorgesehenen code-Tags packen, damit das verstaendlich ist - sonst gehen die in Python relevanten Einrueckungen verloren.

Re: Websocket

Verfasst: Mittwoch 12. April 2023, 09:53
von Sirius3
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, keine Tabs.
Variabelnamen sollten sprechend sein, einbuchstabige Namen sind das aber in der Regel nicht. Niemand (auch du nicht) kann mit t, u, v, w oder z etwas anfangen. Und statt mit Kommentaren zu beschreiben, was `m` bedeutet, wäre es besser gleich `number_of_measurement_runs` zu schreiben.
Globale Variablen benutzt man nicht; wenn man in Call-Backs Variablen braucht, dann schreibt man eine Klasse.
Der `format`-Aufruf steht da einfach nur rum, ohne irgendeinen Effekt zu haben, der kann weg.
Strings stückelt man nicht mit + zusammen sondern benutzt Formatstrings.
Wenn man Zeiträume messen will, benutzt man time.monotonic, nicht time.time.
Du scheinst zusammengehörige Daten in unterschiedlichen Liste u,v,t zu speichern, das macht man nicht, sondern, wie Du das ja schon mit body machst, in einer gemeinsamen Liste.
Das Hauptprogramm steht in einer Funktion `main`.

Code: Alles auswählen

import websocket
import time

NUMBER_OF_MEASUREMENT_POINTS = 10


class WebsocketService:
    def __init__(self):
        self.active = True
        self.t0 = time.monotonic()
        self.body = []
        self.websocket = websocket.WebSocket()
        # self.websocket.connect = self.on_connect
        self.websocket.close = self.on_close
        self.websocket.error = self.on_error
        # self.websocket.recv = self.on_receive
        # self.websocket.send = self.on_send
        self.websocket.pong = self.on_pong

    # The callback for when the client is connected to the server.
    def on_connect(self, ws):
        print("Connection opened")

    # The callback for when the client is disconnected to the server.
    def on_close(self):
        print("Connection closed")

    # The callback for when the client has an error to the server.
    def on_error(self, ws, error):
        print(error)

    # The callback for when a message is received from the server.
    def on_receive(self, ws, msg):
        topic = msg.topic.split("/")[5]
        payload = msg.payload.decode("utf-8")
        print(f"Received message '{payload}' on topic '{msg.topic}' with QoS {msg.qos}' Count {len(self.body)}")
        time_delta = time.monotonic() - self.t0
        self.body.append((time_delta, topic, payload))

        if len(self.body) > NUMBER_OF_MEASUREMENT_POINTS:
            self.active = False

    # The callback for when a message is published from the server.
    def on_send(self, ws, payload):
        print("Message Sent...")

    def on_pong(self, ws, message):
        print("Got a pong! No need to respond")

    def send(self, message):
        self.websocket.send(message)


def main():
    websocket.enableTrace(True)
    service = WebsocketService()

    # connect to broker
    service.websocket.connect("ws://admin:sauter@192.168.10.70:9001", origin="192.168.10.11", subprotocols=["mqtt"])
    print(service.websocket.getheaders())
    print(service.websocket.getstatus())
    print(service.websocket.getsubprotocol())
    print(service.websocket.ping("This is an optional ping payload"))

    # service.send("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/analog-value/1/present-value", "10.00")
    # wsapp = websocket.WebSocketApp("ws://192.168.10.70:9001/sauter/ecos504/411001065754/status/", on_message=on_message)

    # Start the loop
    # wsapp.run_forever(http_proxy_host=host, http_proxy_port=port, http_proxy_auth=(username, password))
    # Smart Sensor datas

    # Loop Bedingung
    # while active:
    # time.sleep(1)
    # Bedingung Erfüllt Loop wird gestoppt
    # wsapp.on_close
    # Messung Ende, Schnittstelle freigeben
    service.websocket.close()

if __name__ == "__main__":
    main()
Warum glaubst Du überhaupt, dass `ping` einen Rückgabewert hat?

Re: Websocket

Verfasst: Mittwoch 12. April 2023, 10:50
von pascal.buehler
Ping nicht direkt, aber nachfolgend vom Ping auf das pong sollte der gleiche string zurückkommen.

Re: Websocket

Verfasst: Mittwoch 12. April 2023, 13:37
von Sirius3
Du wartest den PONG aber gar nicht ab.

Re: Websocket

Verfasst: Donnerstag 13. April 2023, 06:38
von pascal.buehler
mache ich nicht? war mir so nicht bewusst, wie macht man dann das?

müsste ich dann ein .recv(pong()) machen ?

Re: Websocket

Verfasst: Donnerstag 13. April 2023, 08:04
von Sirius3
Code zu raten ist selten sinnvoll. Am besten fängt man mit dem Lesen der Dokumentation zum jeweiligen Paket an.
Bei websocket braucht man eine Ereignisschleife, die die ankommenden Nachrichten auch verarbeitet, und die entsprechenden Callbacks (hier on_pong) auch aufruft. Das fehlt bei Dir alles.

Re: Websocket

Verfasst: Donnerstag 13. April 2023, 08:46
von pascal.buehler
Ja, da muss ich nochmals über read the docs.
Zeigt auch, dass die Beispiele dort nicht die besten sind und dass im Netz oftmals nur read the docs rezitiert wird. :-)