2 Websockets gelichzeitig

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
dimmu
User
Beiträge: 3
Registriert: Freitag 19. August 2016, 08:19

Hallo alle zusammen,

ich bin neu in der Python Welt und stehe nun vor einem Problem was ich nur durch mitlesen und Recherchieren im Forum noch nicht lösen konnte. Es kann gut sein das die Antwort zwar schon mal genannt wurde, nur das ich sie eben noch nicht verstanden habe :K .

Ich habe bis jetzt zwei Scripte gebastelt die Websocket Verbindungen aufbauen.
Das eine Script macht eine Verbindung zu einem Bose Soundtouch Lautsprecher auf, das andere Scrip mache eine Verbindung zu einem Loxone Miniserver auf.
Nach viel Probieren und lesen hat das auch so weit funktioniert.

Nun zum eigentlichen Problem.
Ich wollte wenn sich etwas am Lautsprecher ändert das zum Miniserver senden, oder wenn sich am Miniserver etwas ändert das zum Lautsprecher senden.
Nun weiß ich nicht wie ich am sinnvollsten genau diese Verbindung herstelle.
Also jetzt lieber die beiden Programme in eines zusammen bauen. Das war bisher mein Ansatz, habe es auch schon geschafft beide Websockets auf zu machen, allerdings empfange ich nur noch Daten von dem Socket den ich als zweites geöffnet habe.

Der zweite Ansatz der mir einfällt wäre Daten zwischen den Scripen auszutauschen und das so irgendwie zu realisieren. Leider fehlt mir dafür komplett die zündende idee.

Auch für ganz neue Ansätze bin ich offen.

Achso, ich nutzte den websocket über import websocket.
Die Programme kann ich im Moment leider nicht hochladen da ich am falschen PC sitze.

Ich bin mir sicher hier hat jemand einen Wink für mich der den Knoten im Kopf auslösen kann.
Danke schon mal
dimmu
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@dimmu: man kann mehrere Websockets gleichzeitig geöffnet haben. Mehr kann man dazu im Moment nicht sagen, da wir nicht wissen, wie Du das gelöst hast und welchen Fehler Du dabei gemacht hast.
dimmu
User
Beiträge: 3
Registriert: Freitag 19. August 2016, 08:19

Hallo Sirius3, das geht ja echt schnell bei dir.

zum Glück ist heute Freitag und ich kann zeitig in der Arbeit gehen.
Jetzt bin ich am PC mit den scripten:

Hier mal die nr. 1. Das wäre das was eine Verbindung zum Lautsprecher aufbauen kann.

Code: Alles auswählen

# -*- coding: utf-8 -*- 
import websocket
import thread
import time
from hashlib import sha1
import hmac
import urllib

def on_connectionState():
	print ("update vom Bose")
        return()

## Ab hier ist der Socket aufgebaut und die Antworten können ausgewertet werden.
def on_Bose_message(Bose_ws, message):
	##deviceID //Herausfinden um die richtige URL anzusprechen.
	deviceID = message[message.find("deviceID=")+10:message.find("'",message.find("deviceID=")+10)]
	##updated //message kürzen auf die noch verbleibende nutzinfo
	updated = message[message.find("<updates deviceID")+33:message.find("</updates>")]
	##whoUpdated //Herausfinden was Upgedated wurde
	whoUpdated = updated[1:updated.find("Updated")]
	if whoUpdated == "connectionState":
		on_connectionState()
	else:
		print ("es geht um etwas anders")



def on_Bose_error(Bose_ws, error):
    print(error)

def on_Bose_close(Bose_ws):
    print ("closed")

def on_Bose_open(Bose_ws):
	print('opened')	


if __name__ == "__main__":
	websocket.enableTrace(True)
	
	Bose_ws = websocket.WebSocketApp("ws://192.168.41.40:8080",
	                      subprotocols = ["gabbo"],
                              on_message = on_Bose_message,
                              on_error = on_Bose_error,
                              on_close = on_Bose_close)
	Bose_ws.on_open = on_Bose_open
	Bose_ws.run_forever()

Das hier ist die Verbindung zum Miniserver

Code: Alles auswählen

# -*- coding: utf-8 -*- 
import websocket
import thread
import time
from hashlib import sha1
import hmac
import urllib

def on_Lox_message(Lox_ws, message):
	# Autentifizierung und struktuerdatei downloaden
	if message.find("LL")!= -1:	
		control = message[message.find("\"",message.find("control")+9)+1:message.find("/",message.find("control")+9)]
		if control == "jdev":
			key = message[message.find("\"",message.find("value")+7)+1:message.find("\",",message.find("value")+7)]
			raw_key = key.decode('hex')
			raw = "admin:admin" #Benutzer und Passwort
			hashed = hmac.new(raw_key, raw, sha1)
			encoded = hashed.digest().encode("hex").rstrip('\n')
			encoded = '%s%s' % ("authenticate/", encoded)
			Lox_ws.send(encoded)
		elif control == "authenticate":
			Lox_ws.send("jdev/sps/enablebinstatusupdate")
		elif control =="dev":
			print ("jetzt kommt der download")
			Lox_ws.send("data/LoxAPP3.json")
	else:
		raw_message = message.encode('hex')
		#Testknopf auswerten
		if raw_message == "4e29570e3f008413ffff1239b12ff514000000000000f03f":
			print("test = Ein")
		elif raw_message == "4e29570e3f008413ffff1239b12ff5140000000000000000":
			print("test = Aus")

	print ("fertig")
	return()

def on_Lox_error(Lox_ws, error):
	print (error)

def on_Lox_close(Lox_ws):
	print ("### closed ###")

def on_Lox_open(Lox_ws):
	print ("Key anfordern:")
	Lox_ws.send("jdev/sys/getkey")


if __name__ == "__main__":
	websocket.enableTrace(True)
	
	Lox_ws = websocket.WebSocketApp("ws://192.168.41.130:80/ws/rfc6455",
                              subprotocols = ["remotecontrol"],
                              on_message = on_Lox_message,
                              on_error = on_Lox_error,
                              on_close = on_Lox_close)
        Lox_ws.on_open = on_Lox_open
        Lox_ws.run_forever()

und hier noch die Variante wo ich versucht habe beides in 1 zu mischen. es sind zwei Kommentare enthalten was ich versucht habe und was die Ergebnisse dabei waren.

Code: Alles auswählen

# -*- coding: utf-8 -*- 
import websocket
import thread
import time
from hashlib import sha1
import hmac
import urllib

def on_Lox_message(Lox_ws, message):
	# Autentifizierung und struktuerdatei downloaden
	if message.find("LL")!= -1:	
		control = message[message.find("\"",message.find("control")+9)+1:message.find("/",message.find("control")+9)]
		if control == "jdev":
			key = message[message.find("\"",message.find("value")+7)+1:message.find("\",",message.find("value")+7)]
			raw_key = key.decode('hex')
			raw = "admin:admin" #Benutzer und Passwort
			hashed = hmac.new(raw_key, raw, sha1)
			encoded = hashed.digest().encode("hex").rstrip('\n')
			encoded = '%s%s' % ("authenticate/", encoded)
			Lox_ws.send(encoded)
		elif control == "authenticate":
			Lox_ws.send("jdev/sps/enablebinstatusupdate")
		elif control =="dev":
			print ("jetzt kommt der download")
			Lox_ws.send("data/LoxAPP3.json")
	else:
		raw_message = message.encode('hex')
		#Testknopf auswerten
		if raw_message == "4e29570e3f008413ffff1239b12ff514000000000000f03f":
			print("test = Ein")
		elif raw_message == "4e29570e3f008413ffff1239b12ff5140000000000000000":
			print("test = Aus")

	print ("fertig")
	return()
	
def on_connectionState():
	print ("update vom Bose")
        return()

## Ab hier ist der Socket aufgebaut und die Antworten können ausgewertet werden.
def on_Bose_message(Bose_ws, message):
	##deviceID //Herausfinden um die richtige URL anzusprechen.
	deviceID = message[message.find("deviceID=")+10:message.find("'",message.find("deviceID=")+10)]
	##updated //message kürzen auf die noch verbleibende nutzinfo
	updated = message[message.find("<updates deviceID")+33:message.find("</updates>")]
	##whoUpdated //Herausfinden was Upgedated wurde
	whoUpdated = updated[1:updated.find("Updated")]
	if whoUpdated == "connectionState":
		on_connectionState()
	else:
		print ("es geht um etwas anders")


	#so wird er geöffnet wenn der Bose offen ist. Antworten vom Bose werden aber nicht mehr gesehen
        Lox_ws = websocket.WebSocketApp("ws://192.168.41.130:80/ws/rfc6455",
                              subprotocols = ["remotecontrol"],
                              on_message = on_Lox_message,
                              on_error = on_Lox_error,
                              on_close = on_Lox_close)
        Lox_ws.on_open = on_Lox_open
        Lox_ws.run_forever()




def on_Lox_error(Lox_ws, error):
	print (error)

def on_Lox_close(Lox_ws):
	print ("### closed ###")

def on_Lox_open(Lox_ws):
	print ("Key anfordern:")
	Lox_ws.send("jdev/sys/getkey")


def on_Bose_error(Bose_ws, error):
    print(error)

def on_Bose_close(Bose_ws):
    print ("closed")
    #hier wird er erst geöffnet wenn Bose geschlossen

def on_Bose_open(Bose_ws):
	print('opened')	


if __name__ == "__main__":
	websocket.enableTrace(True)
	
	Bose_ws = websocket.WebSocketApp("ws://192.168.41.40:8080",
	                      subprotocols = ["gabbo"],
                              on_message = on_Bose_message,
                              on_error = on_Bose_error,
                              on_close = on_Bose_close)
	Bose_ws.on_open = on_Bose_open
	Bose_ws.run_forever()

	
	#So wird er gar nicht geöffnte wenn der Bose geschlossen wurde...... 
	Lox_ws = websocket.WebSocketApp("ws://192.168.41.130:80/ws/rfc6455",
                              subprotocols = ["remotecontrol"],
                              on_message = on_Lox_message,
                              on_error = on_Lox_error,
                              on_close = on_Lox_close)
        Lox_ws.on_open = on_Lox_open
        Lox_ws.run_forever()

Ich hoffe man kann über die sonstigen schönheitsmankos im Code ein bisschen hinwegsehen :D :D .
Danke
Zuletzt geändert von Anonymous am Freitag 19. August 2016, 12:04, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@dimmu: Deine Einrückungen sind kaputt. Das liegt wahrscheinlich daran, dass Du Tabs und Leerzeichen mischst. Nimm niemals Tabs sondern immer 4 Leerzeichen pro Ebene. In Python2 sind print-Statements keine Funktionen, sollten also auch nicht als solche (mit Klammern) geschrieben werden. Das Modul thread wird importiert aber nicht benutzt, sollte auch nicht benutzt werden, da es schon lange von threading abgelöst wurde. XML-Daten dürfen nicht wie einfacher Text behandelt werden. Nimm einen XML-Parser (ElementTree) statt per find zu arbeiten. Was diese Lox an Datenformat benutzt, kann ich nicht erkennen, aber falls das JSON ist, dazu gibt es auch einen Parser, den Du benutzen solltest.

Zum eigentlichen Problem: Was glaubst Du was "run_forever" tut?
dimmu
User
Beiträge: 3
Registriert: Freitag 19. August 2016, 08:19

Hallo Sirius3,

das mit dem Einrücken ist mir auch schon aufgefallen. Ich wollte es eigentlich Konsequent mit Tab machen, aber wenn Leerzeichen besser sind stelle ich das um.
Die Klammern um die print sind von einem test als Python3. Die kann ich aber auch entfernen.
ElementTree hatte ich auch schon gefunden, nur nicht direkt verstanden. Deshalb hatte ich mich zunächst auf das konzentriert was ich ich schon wusste und wollte erst mal die Verbindung herstellen. :mrgreen:
der Lox nutzt übrigens tatsächlich json, gut erahnt. Hier werde ich dann auch noch umstellen.

nun auch von mir zurück zum eigentlichen Problem. So wie ich es verstanden bzw. getestet habe, macht das run_forever() das der Websocket offen bleibt.
In irgend einem vergangen Versuch hatte ich das auch ganz am Ende der Main Funktion. Ich meine es wurde aber trotzdem nur einer ausgeführt.
So wie es jetzt sehe stehe doch noch weiter am Anfang wie ich dachte.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

dimmu hat geschrieben:In irgend einem vergangen Versuch hatte ich das auch ganz am Ende der Main Funktion. Ich meine es wurde aber trotzdem nur einer ausgeführt.
So wie es jetzt sehe stehe doch noch weiter am Anfang wie ich dachte.
`run_forever` "arbeite/laufe bis an dein Lebensende", die Funktion beendet niemals, d.h. dein zweites `run_forever` für das zweite Websocket wird niemals ausgeführt. Üblicherweise hat eine solche Bibliothek einen Weg um mit mehreren Verbindungen gleichzeitig umzugehen (KEINE THREADS!).

Theoretisch kannst du auch gevent zuhilfe nehmen, deine Websockets erstellen, dann die gevent mainloop laufen lassen. Ansonsten musst du dich nach alternativen umsehen, z.B. Autobahn.ws.
the more they change the more they stay the same
Antworten