SocketServer und epoll
Verfasst: Montag 28. Januar 2013, 01:04
Nabend,
ich bin ein kompletter Python-Neuling und komme zu euch weil ich ein wenig mit meinem Raspberry Pi rumspielen möchte.
Jetzt habe ich ein Problem damit in Python einen SocketServer ans laufen zu bekommen, der per epoll auf Daten wartet.
Aber am besten ich erkläre es an Beispielen.
Folgendes Skript habe ich geschrieben:
Das funktioniert grundsätzlich auch wie vorgesehen, hat aber zwei gravierende Nachteile:
1. Die Hardware-Tasten funktionieren nur wenn das Script mit der AndroidApp (oder sonst einer Gegenstelle) eine Verbindung hergestellt hat.
2. Sowie ich die App schliesse (oder clientseitig die Verbindung ändere) beendet sich auch das Script.
Deshalb die Lösung -> ein SocketServer muss her.
Dazu habe ich auch schon etwas gefunden
Damit hat zumindest die Kommunikation mit der App geklappt.
Also habe ich mich dran gesetzt und versucht beide Scripts zu verbinden.
Dabei ist dann folgendes herausgekommen
Der erste Erfolg, das Script startet ohne Fehler. Der zweite Erfolg, auch wenn ich die App beende läuft die App weiter.
Aber, leider reagiert das Script nun gar nicht mehr auf die Eingaben die übers Netzwerk kommen.
Ich denke das Problem liegt hier oder schon irgendwo vorher wo das Ereignis registriert wird.
Und versuche ich direkt nach dem Start des Script die Hardware-Taste funktioniert sie nicht. Erst wenn ich die App gestartet habe (und einmal Verbindung hatte) geht die Taste, dann allerdings auch wenn die App wie geschlossen ist.
Anscheinend muss zur Initialisierung erst 1 x eine Verbindung aufgebaut sein.
Und nun meine Bitte an Euch:
Kann mir irgendwer sagen was ich wie ändern muss damit das Programm wieder auf die Netzwerkbefehle reagiert?
Und kann sich jemand die Geschichte mit dem Hardware-Button erklären?
ich bin ein kompletter Python-Neuling und komme zu euch weil ich ein wenig mit meinem Raspberry Pi rumspielen möchte.
Jetzt habe ich ein Problem damit in Python einen SocketServer ans laufen zu bekommen, der per epoll auf Daten wartet.
Aber am besten ich erkläre es an Beispielen.
Folgendes Skript habe ich geschrieben:
Code: Alles auswählen
import socket
from quick2wire.gpio import GPIOPin, In, Out, Pin, exported
import select
pin_bed = 0
pin_bed_switch = 4
pin_nightlight = 3
#light_bed = GPIOPin(pin_bed, direction=Out)
#light_bed_switch = GPIOPin(pin_bed_switch, Pin.In, Pin.Rising)
#light_nightlight = GPIOPin(pin_nightlight, direction=Out)
HOST = ''
PORT = 54321
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with exported(GPIOPin(pin_bed, direction=Out)) as light_bed, exported(GPIOPin(pin_bed_switch, Pin.In, Pin.Rising)) as light_bed_switch, exported(GPIOPin(pin$
epoll = select.epoll()
epoll.register(light_bed_switch, select.EPOLLIN | select.EPOLLET)
epoll.register(conn, select.EPOLLIN | select.EPOLLET)
while True:
events = epoll.poll()
for fileno, event in events:
if fileno == light_bed_switch.fileno():
if light_bed.value:
light_bed.value = 0
else:
light_bed.value = 1
if fileno == conn.fileno():
data = conn.recv(1024)
if data == 'Lampe Bett on\n':
conn.send('on')
light_bed.value = 1
elif data == 'Lampe Bett off\n':
conn.send('off')
light_bed.value = 0
elif data == 'Lampe Nachtlicht on\n':
conn.send('off')
light_nightlight.value = 1
elif data == 'Lampe Nachtlicht off\n':
conn.send('off')
light_nightlight.value = 0
elif data == 'get status_lampe_bett\n':
if light_bed.value:
conn.send('on')
else:
conn.send('off')
elif data == 'get status_lampe_nachtlicht\n':
if light_nightlight.value:
conn.send('on')
else:
conn.send('off')
else:
conn.send('unknown command')
conn.close()
1. Die Hardware-Tasten funktionieren nur wenn das Script mit der AndroidApp (oder sonst einer Gegenstelle) eine Verbindung hergestellt hat.
2. Sowie ich die App schliesse (oder clientseitig die Verbindung ändere) beendet sich auch das Script.
Deshalb die Lösung -> ein SocketServer muss her.
Dazu habe ich auch schon etwas gefunden
Code: Alles auswählen
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
while 1:
self.data = self.request.recv(1024).strip()
if not self.data: break
print "{} wrote:".format(self.client_address[0])
print self.data
self.request.sendall('100')
if __name__ == "__main__":
HOST, PORT = "", 54321
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
Also habe ich mich dran gesetzt und versucht beide Scripts zu verbinden.
Dabei ist dann folgendes herausgekommen
Code: Alles auswählen
from quick2wire.gpio import GPIOPin, In, Out, Pin, exported
import select
import SocketServer
pin_bed = 0
pin_bed_switch = 4
pin_nightlight = 3
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
while True:
events = epoll.poll()
for fileno, event in events:
if fileno == light_bed_switch.fileno():
if light_bed.value:
light_bed.value = 0
else:
light_bed.value = 1
if fileno == server.fileno():
self.data = self.request.recv(1024).strip()
print self.data
if data == 'Lampe Bett on\n':
self.send('on')
light_bed.value = 1
elif data == 'Lampe Bett off\n':
self.send('off')
light_bed.value = 0
elif data == 'Lampe Nachtlicht on\n':
self.send('off')
light_nightlight.value = 1
elif data == 'Lampe Nachtlicht off\n':
self.send('off')
light_nightlight.value = 0
elif data == 'get status_lampe_bett\n':
if light_bed.value:
self.send('on')
else:
self.send('off')
elif data == 'get status_lampe_nachtlicht\n':
if light_nightlight.value:
self.send('on')
else:
self.send('off')
else:
self.send('unknown command')
if __name__ == "__main__":
HOST, PORT = "", 54321
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
with exported(GPIOPin(pin_bed, direction=Out)) as light_bed, exported(GPIOPin(pin_bed_switch, Pin.In, Pin.Rising)) as light_bed_switch, exported(GPIOPin(pin_nightlight, direction=Out)) as light_nightlight:
light_bed.value = 0
light_nightlight.value = 0
epoll = select.epoll()
epoll.register(light_bed_switch, select.EPOLLIN | select.EPOLLET)
epoll.register(server, select.EPOLLIN | select.EPOLLET)
server.serve_forever()
Aber, leider reagiert das Script nun gar nicht mehr auf die Eingaben die übers Netzwerk kommen.
Ich denke das Problem liegt hier
Code: Alles auswählen
if fileno == server.fileno():
Und versuche ich direkt nach dem Start des Script die Hardware-Taste funktioniert sie nicht. Erst wenn ich die App gestartet habe (und einmal Verbindung hatte) geht die Taste, dann allerdings auch wenn die App wie geschlossen ist.
Anscheinend muss zur Initialisierung erst 1 x eine Verbindung aufgebaut sein.
Und nun meine Bitte an Euch:
Kann mir irgendwer sagen was ich wie ändern muss damit das Programm wieder auf die Netzwerkbefehle reagiert?
Und kann sich jemand die Geschichte mit dem Hardware-Button erklären?