Page 1 of 1
Websocketserver in Python (twisted + autobahn)
Posted: Thu Sep 06, 2012 2:07 pm
by schelli04
Hallo zusammen!
Vorab: ich bin ziemlicher Einsteiger. Programmierung läuft bei mir zu 90% Copy&Paste
Bin momentan dabei mir daheim ne kleine Alarmanlage zusammenzubauen. Das Script zur Überwachung der GPIO Pins ist fertig (Python). Zu An und Aus schalten der Alarmanlage habe ich ne kleine Webapp mit Websocketverbindung erstellt. Der Websocketserver (twisted + autobahn) läuft auch als einzelnes Script in Python. Das Problem ist, dass das Script nur auf Verbindungsereignisse reagiert, ich also die Schleife, die die GPIO's überwacht nicht im selben Script laufen lassen kann. Hat jemand ne Idee, wie ich das bewerkstelligen kann, dass beide Scripte miteinander kommunizieren?
Wenn ich daheim bin füge ich noch ein den Quelltext mit ein.
Gruß Schelli
Re: Websocketserver in Python (twisted + autobahn)
Posted: Thu Sep 06, 2012 5:18 pm
by schelli04
So ich habe es nun am laufen. Die Kommunikation läuft über eine Datei (comm.ini)
Das ist der Code der eigentlichen Alarmanlage:
Code: Select all
import smsgateway, emailsenden, sys
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM) # BCM - Modus verwenden
GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_UP) # GPIO 4 als Eingang setzen
GPIO.setup(0, GPIO.OUT)
aktiv = False # Bei Start Alarmanlage deaktiviert
print aktiv
while True:
while aktiv != True: # Solange Alarmanlage nicht aktiv
File = open('comm.ini', 'w+')
msg = File.read()
File.write('')
File.close()
if msg=='on': # Warten auf Aktivierung
aktiv = True
print aktiv
if msg=='status':
File = open('comm.ini', 'w')
if aktiv:
status = 'Aktiv'
else:
status = 'Inaktiv'
File.write(status)
File.close
while aktiv:
GPIO.output(0, True)
if False:#GPIO.input(4) != 0: # Wenn Tuer geoeffnet wird
#smsgateway.sms('Tuer geoeffnet')
emailsenden.send('Tuer geoeffnet')
aktiv = False
File = open('comm.ini', 'w+')
msg = File.read()
File.write('')
File.close()
if msg=='off': # Warten auf Deaktivierung
aktiv = False
print aktiv
if msg=='status':
File = open('comm.ini', 'w')
if aktiv:
status = 'Aktiv'
else:
status = 'Inaktiv'
File.write(status)
File.close
Und hier der Code des Websocket-Servers:
Code: Select all
import sys, time
from twisted.internet import reactor
from twisted.python import log
from autobahn.websocket import WebSocketServerFactory, \
WebSocketServerProtocol, \
listenWS
class EchoServerProtocol(WebSocketServerProtocol):
def onMessage(self, msg, binary):
print msg
if msg == "on":
file = open('comm.ini', 'w+')
file.write('on')
file.close()
self.sendMessage('AN', binary)
if msg == "off":
file = open('comm.ini', 'w+')
file.write('off')
file.close()
self.sendMessage('AUS', binary)
if msg == "status":
file = open('comm.ini', 'w+')
file.write('status')
file.close()
time.sleep(2)
file = open('comm.ini', 'r')
bmsg = file.read()
file.close()
file = open('comm.ini', 'w')
file.write('')
file.close()
self.sendMessage(bmsg, binary)
print 'Status', bmsg
if __name__ == '__main__':
#log.startLogging(sys.stdout)
factory = WebSocketServerFactory("ws://192.168.0.191:9123", debug = False)
factory.protocol = EchoServerProtocol
factory.setProtocolOptions(allowHixie76 = True)
listenWS(factory)
reactor.run()
Vielleicht hat jemand einen Tip wie ich das ganze besser lösen kann. Habe das Gefühl, dass das Alarmanlagenskript oft die Datei blockiert.
Re: Websocketserver in Python (twisted + autobahn)
Posted: Fri Sep 07, 2012 9:13 am
by oberstet
Generell sollte in Twisted Code niemals blockierender Code aufgerufen werden. Für die Kommunikation über Serial Ports gibt es
http://twistedmatrix.com/documents/curr ... lPort.html. Um blockierenden Code in einem eigenem Thread auszuführen gibt es deferToThread u.ä. Funktionen.
Re: Websocketserver in Python (twisted + autobahn)
Posted: Sun Sep 09, 2012 12:43 pm
by schelli04
Danke für den Tip! Werde mich diesbezüglich mal einlesen. Neue Lösung werde ich dann hier einstellen wenn es läuft.
Re: Websocketserver in Python (twisted + autobahn)
Posted: Sun Sep 09, 2012 5:45 pm
by schelli04
So habe nun die "Alarmüberwachung" in einen eigenen Thread gepackt. Läuft bis jetzt ohne erkennbare Probleme und Verzögerung. Wesentliche bessere Lösung als mein erster Ansatz mit der Datei.
Vollständiger Code:
Code: Select all
import time
import sys # Modul fuer Dateioperationen
import RPi.GPIO as GPIO
import thread
import smsgateway, emailsenden
from twisted.internet import reactor
from twisted.python import log
from autobahn.websocket import WebSocketServerFactory, \
WebSocketServerProtocol, \
listenWS
# GPIO nach BCM initalisieren
GPIO.setmode(GPIO.BCM)
# GPIO Eingang setzen
GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Status LED setzen
GPIO.setup(14, GPIO.OUT)
status = False
class EchoServerProtocol(WebSocketServerProtocol):
def onMessage(self, msg, binary):
global status
print msg
if msg == "on":
status = True
if msg == "off":
status = False
self.sendMessage(str(status), binary)
print 'Status', str(status)
def alarm():
global status
while True:
while status:
GPIO.output(14, True)
if GPIO.input(4) == 0: # Wenn Tuer geoeffnet wird '==' muss im endgueltigen Zustand in '!=' geaendert werden. Aktuell reagiert die Schleife auf Tastendruck
#smsgateway.sms('Tuer geoeffnet')
#emailsenden.send('Tuer geoeffnet')
print str(status)
status = False
GPIO.output(14, False)
if __name__ == '__main__':
log.startLogging(sys.stdout)
factory = WebSocketServerFactory("ws://192.168.0.191:9123", debug = False)
factory.protocol = EchoServerProtocol
factory.setProtocolOptions(allowHixie76 = True)
listenWS(factory)
thread.start_new_thread(alarm, ())
reactor.run()
In Zeile 41 wird zu Testzwecken nur auf den Tastendruck reagiert. Im finalen Stadium soll reagiert werden wenn ein an der Tür angebrachter Reedkontakt geöffnet ist.
Re: Websocketserver in Python (twisted + autobahn)
Posted: Sun Sep 09, 2012 5:51 pm
by oberstet
Das wird nicht (robust) funktionieren .. denn Du möchtest ja von dem Hintergrund Thread aus Messages über WebSocket versenden und letzteres läuft im Twisted Main Thread => callFromThread.
http://twistedmatrix.com/documents/curr ... ading.html
Re: Websocketserver in Python (twisted + autobahn)
Posted: Mon Sep 10, 2012 6:40 am
by schelli04
(Vorerst) sollen per Websocket nur Nachrichten geschickt werden, wenn welche empfangen werden. Sozusagen als Statusmeldung. Das Funktioniert ja. Die Alarmmeldung selber geht per SMS raus, weil ich ja sonst ständig mit der WebApp online sein müsste, um die Nachrichten zu empfangen.
Werds mir dein Link trotzdem mal anschauen, da ich noch weitere Funktionen mit einbauen wollte.
Re: Websocketserver in Python (twisted + autobahn)
Posted: Tue Sep 11, 2012 9:43 am
by oberstet
Wie machst Du das SMS versenden? Würde mich auch interessieren ..
Re: Websocketserver in Python (twisted + autobahn)
Posted: Tue Sep 11, 2012 12:31 pm
by schelli04
Ich habe mir ein Account unter
http://www.sms-expert.de angelegt. Der Versand erfolgt dann über einen http-Request. Da kostet die SMS allerdings 0,05 €.
Code: Select all
import urllib, urllib2, time
import md5
from config import smsuser, smspasswd
def sms(message, nr):
url = 'https://gateway.sms-expert.de/send/'
user = smsuser
type = 'standard'
receiver = str(nr)
hashstring = user + '|' + str(smspasswd) + '|' + type + '||' + receiver + '|' + message + '|'
print hashstring
hash = md5.new(hashstring).hexdigest()
print hash
values = { 'user':user,
'type':type,
'receiver':receiver,
'message':message,
'hash':hash}
try:
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
antwort = response.read()
print antwort
except Exception, detail:
print "Err ", detail
smsuser und smspasswd sind die Zuganngsdaten zum SMS-Gateway. Habe ich in ner extra Datei config.py gespeichert.
Später wollte ich das ganze aber mit Hilfe eines UMTS Stick mit SIM-Karte machen, damit das ganze nicht auf mein Heimnetzwerk angewiesen ist. Also der Versand direkt über den UMTS-Stick ohne das zusätzliche Gateway im Netz.
Re: Websocketserver in Python (twisted + autobahn)
Posted: Wed Mar 05, 2014 10:20 am
by theTimewalker
Hallo schelli04,
habe deinen Beitrag gerade zufällig gefunden und wollte mal fragen ob du den SMS-Versand per UMTS-Stick inzwischen umgesetzt hast. Wenn ja, wäre ich um eine kurze Hilfestellung (Anleitung oder Links) sehr dankbar...
VG,
Timewalker
Re: Websocketserver in Python (twisted + autobahn)
Posted: Thu Mar 13, 2014 6:43 am
by schelli04
Hey Timewalker,
da ich mich zwischenzeitlich mit anderen Projekten beschäftigt habe, bin ich noch nicht dazu gekommen den SMS-Versand über einen UMTS-Stick zu realisieren. In nächster Zeit werde ich auch die Zeit dazu nicht finden.
MfG, Schelli